使用Java/CORBA实现分布应用编程

  • Post author:
  • Post category:java



一、学习

JAVA与CORBA

■CORBA技术简介


简单地说,

CORBA允许应用之间相互通信,而不管它们存在于哪里以及是谁设计的。CORBA1.1于1991年由OMG发布,其中定义了接口定义语言(IDL)以及在对象请求代理(ORB)中实现客户对象与服务器对象之间交互的应用编程接口(API)。CORBA2.0于1994年发布,规定了各个供应商之间的ORB的通信规则。

CORBA标准主要分为三个部分:接口定义语言(IDL)、对象请求代理(ORB)以及ORB之间的互操作协议IIOP。

ORB是对象之间建立Client/Server关系的中间件。使用ORB,客户可以透明地调用一个服务对象上的方法,这个服务对象可以在本地,也可以在通过网络连接的其他机器上。ORB截获这一调用同时负责查找实现服务的对象并向其传递参数、调用方法返回最终结果。客户并不知道服务对象位于什么地方,它的编程语言和操作系统是什么,也不知道不属于对象接口的其他系统部分。这样,ORB在异构分布环境下为不同机器上的应用提供了互操作性,并无缝地集成了多种对象系统。


在开发传统的

Client/Server应用时,开发者使用他们自己设计的或一个公认的标准来定义用于设备之间通信的协议。协议的定义依赖于实现语言、网络传输和许多其他因素,而ORB的出现简化了这一过程。使用ORB时,协议是使用接口定义语言(IDL)定义的,而IDL是独立于语言的。并且ORB提供很强的灵活性,它使程序员选择最适合的操作系统、执行环境,甚至系统各个组件也可以采用不同的编程语言实现。更重要的是,它允许现有组件的集成。在一个基于ORB的解决方案中,开发者可以使用与创建新对象一样的IDL对遗留系统进行建模,他们创建“包装”代码以在标准化的软件总线与遗留系统接口之间传递信息。


使用

CORBA,用户可以透明地访问信息,并不需要知道信息存在于什么软件中、使用什么硬件平台,以及位于企业网络的什么地方。作为面向对象系统的通信核心,CORBA为今天的计算环境带来了真正的互操作性。

■CORBA与JAVA的相互关系

CORBA不只意味着对象请求代理(ORB),它还是非常全面的分布式对象平台。CORBA使JAVA应用可以跨越网络、语言以及操作系统,并为JAVA提供了一组分布服务,如分布式自我观察、动态发现、事务、关系、安全和命名等。

JAVA不仅是一种语言,它还是一个动态代码系统,它对运行对象来说是一个可移植的虚拟机(JVM)。JAVA为开发、管理、发布Client/Server应用提供了更简单的方式。人们可以通过将应用放在一个Web服务器上将这一应用发布给成千上万个用户,而不必关心它的安装和升级。JAVA还非常适合服务器的开发,它可以动态地将服务代码移向最需要它们的地方。

JAVA将会使CORBA对象能够运行在从主机、网络计算机到蜂窝电话等可编程的各种机器上,并简化了大型CORBA系统的代码发布。对客户和服务对象来说JAVA是很理想的编程语言,JAVA内置的多线程、垃圾收集和错误处理使编写健壮的网络对象变得很容易。


这两种对象模型可以很好地相互补充,

CORBA处理网络的透明性,JAVA处理实现的透明性,CORBA为JAVA可移植应用环境提供了一个分布式的结构。

二、

按照网上教程配置

CORBA环境

三、构建程序代码

1.使用IDL语言为远程对象定义接口,根据题目要求,需要两个接口,一个实现用户的注册和登录,一个实现用户对list的增删改查

creator.idl:

module CreatorModule{
    interface Creator{
        boolean login(in string name,in string password);
        boolean register(in string name,in string password);
    };
};

userOperation.idl:

module UserModule{
    interface UserOperation{
        boolean add(in string startTime,in string endTime,in string label);
        string query(in string startTime,in string endTime);
        boolean delete(in string key);
        boolean clear();
        string show();
    };
};

2.

编译接口并生成

CORBA支持文件




CreatorModule目录下的六个文件说明如下:




1) Creator.java:此接口包含IDL接口的Java版本。它继承自org.omg.CORBA.Object,提供标准的CORBA对象功能。




2)CreatorHelper.java : 此类提供辅助功能,Helper类负责读写数据类型到CORBA流,以及插入和提取数据类型。




3)CreatorHolder.java : 此类是一个终态类,其中含有Creator类型的公有数据成员。




4)CreatorOperations.java : 这是一个接口类,其中含有在creator.idl文件中编写的接口方法。




5)CreatorPOA.java : 此抽象类是基于流的服务器Skeleton,为服务器提供基本的CORBA功能。它继承org.omg.PortableServer.Servant, 实现了InvokeHandler接口和CreatorOperations接口。以后编写的服务器类要继承CreatorPOA。




6)_CreatorStub.java : 此类是客户端stub,为客户端提供CORBA功能。它继承org.omg.CORBA.Object,提供标准CORBA对象功能。还扩展了 CreatorOperations接口和org.omg.CORBA.portable.IDLEntity接口。

UserModule目录下的文件意义和上面类似。

3.

编写

User类和Item类来分别存储用户以及list内的Item

import java.io.Serializable;
public class User implements Serializable {
    private String name;
    private String password;

    public User(String name, String password) {
        this.name = name;
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public String getPassword() {
        return password;
    }
}

import java.io.Serializable;
import java.util.Date;

public class Item implements Serializable {
    private Date startTime;
    private Date endTime;
    private String label;

    public Item(Date startTime, Date endTime, String label) {
        this.startTime = startTime;
        this.endTime = endTime;
        this.label = label;
    }

    public Date getStartTime() {
        return startTime;
    }

    public Date getEndTime() {
        return endTime;
    }

    public String getLabel() {
        return label;
    }
}

4.

创建

CreatorImpl类和UserOperationImpl来实现两个接口

import CreatorModule.CreatorPOA;
import org.omg.CORBA.ORB;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

public class CreatorImpl extends CreatorPOA {
    private List<User> userList;
    private ORB orb;
    private CORBAServer cServer;

    public CreatorImpl() {
        init();
    }

    //read all users from the file
    private void init() {
        //从文件中读取用户列表,转化为HashMap
        try (ObjectInputStream oin = new ObjectInputStream(new FileInputStream("User.file"))) {
            Object object = oin.readObject();
            userList = (List<User>) object;

        } catch (Exception e) {
            userList = new ArrayList<>();
        }
    }

    public void setORB(ORB orb) {
        this.orb = orb;
    }

    public void setToDoListServer(CORBAServer cServer) {
        this.cServer = cServer;
    }

    //save the all users into the file
    private void saveUsers() {
        try (ObjectOutputStream oout = new ObjectOutputStream(new FileOutputStream("person.file"))) {
            oout.writeObject(userList);
            oout.flush();
        } catch (Exception e) {
            System.out.println("cant save the user");
            e.printStackTrace();
        }
    }


    //register user on the server
    private void registerService(String name) {
        cServer.registerUserName(name);
    }

    @Override
    public boolean login(String name, String password) {
        for (User user : userList) {
            if (user.getName().equals(name) && user.getPassword().equals(password)) {
                registerService(name);
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean register(String name, String password) {
        for (User user : userList) {
            //already have this user
            if (user.getName().equals(name)) {
                return false;
            }
        }
        userList.add(new User(name, password));
        saveUsers();
        return true;
    }

}

import UserModule.UserOperationPOA;
import org.omg.CORBA.ORB;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class UserOperationImpl extends UserOperationPOA {
    private List<Item> userList;                  //this users list
    private Map<String, List<Item>> allUserListMap;   //all users List
    private ORB orb;

    public UserOperationImpl(String name) {
        init();
        userList = allUserListMap.get(name);
        if (userList == null) {
            userList = new ArrayList<>();
            allUserListMap.put(name, userList);
        }

    }

    private void init() {
        //read user list
        try(ObjectInputStream oin = new ObjectInputStream(new FileInputStream("item.file"))) {
            Object object = oin.readObject();
            allUserListMap = (HashMap<String, List<Item>>) object;
        } catch (Exception e) {
            allUserListMap = new HashMap<>();
        }
    }

    public void setORB(ORB orb) {
        this.orb = orb;
    }

    //save user list
    private void saveUserList() {
        try(ObjectOutputStream oout = new ObjectOutputStream(new FileOutputStream("item.file"))) {
            oout.writeObject(allUserListMap);
            oout.flush();
        } catch (Exception e) {
            System.out.println("cant save the list");
            e.printStackTrace();
        }
    }
    @Override
    public boolean add(String startTime, String endTime, String label) {
        try {
            java.text.SimpleDateFormat formatter = new SimpleDateFormat( "yyyy-MM-dd hh:mm:ss");
            Date startDate=formatter.parse(startTime);
            Date endDate=formatter.parse(endTime);
            Item item = new Item(startDate, endDate, label);
            userList.add(item);
            saveUserList();
            return true;
        }catch (ParseException e){
            System.out.println("please input the right date(yyyy-MM-dd hh:mm:ss)");
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public String query(String startTime, String endTime) {
        String queryResult = "";
        try{
            SimpleDateFormat formatter = new SimpleDateFormat( "yyyy-MM-dd hh:mm:ss");
            Date startDate=formatter.parse(startTime);
            Date endDate=formatter.parse(endTime);
                for (Item item : userList) {
                    if (item.getStartTime().after(startDate) && item.getEndTime().before(endDate)) {
                        queryResult +=item.getLabel()+":"+ item.getStartTime() +
                                "--" + item.getEndTime()+ "\n";
                    }
                }
        }catch (ParseException e){
            System.out.println("please input the right date(yyy-MM-dd hh:mm:ss)");
            e.printStackTrace();
        }
        return queryResult;
    }

    @Override
    public boolean delete(String num) {
        int index = Integer.parseInt(num);
        if (index <= userList.size() && index >= 1) {
            userList.remove(index - 1);
            saveUserList();
            return true;
        } else {
            return false;
        }
    }

    @Override
    public boolean clear() {
        int index = userList.size()-1;
        if (index < 0) {
            return false;
        } else {
            while (index >= 0) {
                userList.remove(index);
                index--;
            }
            saveUserList();
            return true;
        }
    }

    @Override
    public String show() {
        String result = "";
        if (userList.size() > 0) {
            for (Item item : userList) {
                result += item.getLabel()+":"+ item.getStartTime() +
                        "--" + item.getEndTime()+ "\n";
            }
        }
        return result;
    }
}

5. 编写服务器端代码

import UserModule.UserOperation;
import UserModule.UserOperationHelper;
import org.omg.CORBA.ORB;
import org.omg.CosNaming.NameComponent;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import CreatorModule.Creator;
import CreatorModule.CreatorHelper;

import java.util.Properties;

public class CORBAServer {
    private ORB orb;
    private POA rootPOA;
    private org.omg.CORBA.Object obj;
    private CreatorImpl creatorImpl;
    private UserOperationImpl userOperationImpl;
    private org.omg.CORBA.Object ref;
    private Creator creatorhref;
    private UserOperation userhref;
    private org.omg.CORBA.Object objRef;
    private NamingContextExt ncRef;

    public static void main(String[] args) {
        CORBAServer toDoListServer = new CORBAServer();
        toDoListServer.init();
    }

    //初始化,注册Creator到服务中
    private void init() {
        try {
            String[] args = {};
            Properties properties = new Properties();

            properties.put("org.omg.CORBA.ORBInitialHost", "127.0.0.1");  //指定ORB的ip地址
            properties.put("org.omg.CORBA.ORBInitialPort", "8080");       //指定ORB的端口

            //创建一个ORB实例
            orb = ORB.init(args, properties);

            //拿到根POA的引用,并激活POAManager,相当于启动了server
            obj = orb.resolve_initial_references("RootPOA");
            rootPOA = POAHelper.narrow(obj);
            rootPOA.the_POAManager().activate();

            //创建一个CreatorImpl实例
            creatorImpl = new CreatorImpl();
            creatorImpl.setToDoListServer(this);

            //从服务中得到对象的引用,并注册到服务中
            ref = rootPOA.servant_to_reference(creatorImpl);
            creatorhref = CreatorHelper.narrow(ref);

            //得到一个根命名的上下文
            objRef = orb.resolve_initial_references("NameService");
            ncRef = NamingContextExtHelper.narrow(objRef);

            //在命名上下文中绑定这个对象
            String name = "Creator";
            NameComponent path[] = ncRef.to_name(name);
            ncRef.rebind(path, creatorhref);

            System.out.println("server is ready and waiting....");

            //启动线程服务,等待客户端调用
            orb.run();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //对用户名进行注册服务
    public void registerUserName(String name) {
        try {
            //创建一个UserImpl实例
            userOperationImpl = new UserOperationImpl(name);
            userOperationImpl.setORB(orb);

            //从服务中得到对象的引用,并注册到服务中
            ref = rootPOA.servant_to_reference(userOperationImpl);
            userhref = UserOperationHelper.narrow(ref);

            //在命名上下文中绑定这个对象
            NameComponent path[] = ncRef.to_name(name);
            ncRef.rebind(path, userhref);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

6. 编写客户端代码

import UserModule.UserOperation;
import UserModule.UserOperationHelper;
import org.omg.CORBA.ORB;
import org.omg.CORBA.ORBPackage.InvalidName;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import org.omg.CosNaming.NamingContextPackage.CannotProceed;
import org.omg.CosNaming.NamingContextPackage.NotFound;
import CreatorModule.Creator;
import CreatorModule.CreatorHelper;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Properties;

public class CORBAClient {
    private Creator creator;
    private UserOperation userOperation;
    private BufferedReader reader;
    private ORB orb;
    private org.omg.CORBA.Object objRef;
    private NamingContextExt ncRef;

    public CORBAClient() {
        reader = new BufferedReader(new InputStreamReader(System.in));
    }

    public static void main(String[] args) {
        CORBAClient CORBAClient = new CORBAClient();
        CORBAClient.init();
        CORBAClient.procedure();
    }


    private void init() {
        System.out.println("Client init config starts....");
        String[] args = {};
        Properties properties = new Properties();
        properties.put("org.omg.CORBA.ORBInitialHost", "127.0.0.1");  //指定ORB的ip地址
        properties.put("org.omg.CORBA.ORBInitialPort", "8080");       //指定ORB的端口

        //创建一个ORB实例
        orb = ORB.init(args, properties);

        //获取根名称上下文
        try {
            objRef = orb.resolve_initial_references("NameService");
        } catch (InvalidName e) {
            e.printStackTrace();
        }
        ncRef = NamingContextExtHelper.narrow(objRef);

        String name = "Creator";
        try {
            //通过ORB拿到server实例化好的Creator类
            creator = CreatorHelper.narrow(ncRef.resolve_str(name));
        } catch (NotFound e) {
            e.printStackTrace();
        } catch (CannotProceed e) {
            e.printStackTrace();
        } catch (org.omg.CosNaming.NamingContextPackage.InvalidName e) {
            e.printStackTrace();
        }

        System.out.println("Client init config ends...");
    }

    //与用户交互
    public void procedure() {
        String choice;
        String startTime, endTime, label;
        String index;

        try {
            while (true) {
                System.out.println("1.Register\n2.Login\n3.Exit");
                choice = reader.readLine();

                switch (choice) {
                    case "1":
                        while (true) {
                            if (register()) {
                                break;
                            }
                        }
                        break;
                    case "2":
                        while (true) {
                            if (login()) {
                                System.out.println("Login Successful!");
                                do {
                                    System.out.println("Please choose following command:");
                                    System.out.println("1.Add item\n" +
                                            "2.Query item\n" +
                                            "3.Show items\n" +
                                            "4.Delete item\n" +
                                            "5.Clear items\n" +
                                            "6.Logout");
                                    choice = reader.readLine();
                                    switch (choice) {
                                        case "1":
                                            System.out.println("please input startTime (like this:2018-05-19 08:20:00):");
                                            startTime = reader.readLine();
                                            System.out.println("please input endTime (like this:2018-05-19 08:20:00):");
                                            endTime = reader.readLine();
                                            System.out.println("please input label:");
                                            label = reader.readLine();
                                            if (userOperation.add(startTime, endTime, label)) {
                                                System.out.println("Add item successful!");
                                            } else {
                                                System.out.println("Add item fail!");
                                            }
                                            break;
                                        case "2":
                                            System.out.println("please input startTime (like this:2018-05-19 08:20:00):");
                                            startTime = reader.readLine();
                                            System.out.println("please input endTime (like this:2018-05-19 08:20:00):");
                                            endTime = reader.readLine();
                                            System.out.println(userOperation.query(startTime, endTime));
                                            break;
                                        case "3":
                                            System.out.println(userOperation.show());
                                            break;
                                        case "4":
                                            System.out.println("please input index:");
                                            index = reader.readLine();
                                            if (userOperation.delete(index)) {
                                                System.out.println("Delete item successful!");
                                            } else {
                                                System.out.println("Delete item fail!");
                                            }
                                            break;
                                        case "5":
                                            if (userOperation.clear()) {
                                                System.out.println("Clear items done!");
                                            }
                                            break;
                                    }
                                } while (!choice.equals("6"));
                                break;
                            } else {
                                System.out.println("Login fail!");
                                break;
                            }
                        }
                        break;
                    case "3":
                        return;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //注册
    private boolean register() {
        String username, password;

        try {
            System.out.println("please input username:");
            username = reader.readLine();
            System.out.println("please input password:");
            password = reader.readLine();
            if (creator.register(username, password)) {
                System.out.println("Register successful!");
                return true;
            } else {
                System.out.println("Register fail!");
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    //登录
    private boolean login() {
        String username, password;

        try {
            System.out.println("please input username:");
            username = reader.readLine();
            System.out.println("please input password:");
            password = reader.readLine();
            if (creator.login(username, password)) {
                try {
                    //通过ORB拿到server实例化好的User类
                    userOperation = UserOperationHelper.narrow(ncRef.resolve_str(username));
                } catch (NotFound e) {
                    e.printStackTrace();
                } catch (CannotProceed e) {
                    e.printStackTrace();
                } catch (org.omg.CosNaming.NamingContextPackage.InvalidName e) {
                    e.printStackTrace();
                }
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}