使用java和CORBA实现分布应用编程

来源:互联网 发布:手机倍投软件 编辑:程序博客网 时间:2024/05/22 07:55

因为课程的需要,学习了下用java和CORBA来实现分布应用编程,具体的CORBA是什么以及它的框架结构我就不多说了,这里我是给出一个比较完整的例子来展示下代码要怎么写。

应用背景:

使用java和CORBA构建一个关于制订to-do-list的分布式应用。不同的客户端可以通过连接到服务器来管理自己的to-do-list,比如有add list items、query list items、delete list items、clear to-do lists、show total list等功能。同时服务器可以管理用户,比如有登录和注册功能。每个to-do list的内容有该做的事、开始时间、结束时间。

具体实现

一、编写IDL接口定义文件
使用IDL语言为远程对象定义接口,根据题目要求,定义IDL文件如下:
(1)在文件creator.idl中:

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

这是用来管理用户的,提供了注册和登陆接口。
(2)在文件user.idl中:

mmodule UserModule{    interface User{        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();    };};

add()、query()、delete()、clear()、show()分别为客户端对to-do-list中的item进行增查删清的操作。

二、将接口定义文件编译为相应高级语言源代码,产生服务器框架与客户端存根
定义好IDL接口文件后,使用idlj编译器生成Java语言的stub和skeleton源文件。idlj编译器缺省只生成客户端的binding代码。如果同时需要客户端的bindings和服务器端的skeletons,必须加上-fall选项。
所以在shell中先后输入命令

idlj -fall /home/huxijie/IntelliJIDEAProjects/ToDoListApp/src/creator.idl

和命令

idlj -fall /home/huxijie/IntelliJIDEAProjects/ToDoListApp/src/user.idl 

后会生成目录CreatorModule和UserModule。两个目录的文件如下:
这里写图片描述
对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目录下的文件意义和上面类似。
三、编写对象类
根据题意,需要编写Person类来抽象化用户以及Item类来抽象化to-do-list中的事项。因为我是将用户列表和事项列表存在本地文件中,所以需要让Person类和Item类实现Serializable序列化。

/** * Created by huxijie on 17-5-3. * 用户类 */public class Person implements Serializable{    private String name;    private String password;    public Person(String name, String password) {        this.name = name;        this.password = password;    }    public String getPassword() {        return password;    }}
/** * Created by huxijie on 17-5-3. * 事项类 */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;    }}

四、接口实现
(一)实现creator.idl中定义的接口

/** * Created by huxijie on 17-5-3. * 实现用户管理creator.idl中定义的接口 */public class CreatorImpl extends CreatorPOA {    private Map<String, Person> personsMap;    private String name = null;    private ORB orb;    private ToDoListServer toDoListServer;    private UserImpl userImpl;    public CreatorImpl() {        init();    }    //初始化    private void init() {        //从文件中读取用户列表,转化为HashMap        try {            FileInputStream fin = new FileInputStream("person.file");            ObjectInputStream oin = new ObjectInputStream(fin);            try {                Object object = oin.readObject();                personsMap = (HashMap<String, Person>) object;            } catch (ClassNotFoundException e) {                System.out.println("object cast error");                personsMap = new HashMap<String, Person>();            }            oin.close();            fin.close();        } catch (Exception e) {            personsMap = new HashMap<String, Person>();        }    }    //将用户表保存到本地文件中    private void saveData() {        try {            FileOutputStream fout = new FileOutputStream("person.file");            ObjectOutputStream oout = new ObjectOutputStream(fout);            oout.writeObject(personsMap);            oout.flush();            fout.flush();            oout.close();            fout.close();        } catch (Exception e) {            System.out.println("save error.");            e.printStackTrace();        }    }    public void setORB(ORB orb) {        this.orb = orb;    }    public void setToDoListServer(ToDoListServer toDoListServer) {        this.toDoListServer = toDoListServer;    }    //对用户名进行注册服务    private void registerService(String name) {        toDoListServer.registerUserName(name);    }    @Override    public boolean login(String name, String password) {        Person p = personsMap.get(name);        if (p != null && p.getPassword().equals(password)) {            this.name = name;            //登录成功后对用户名进行注册服务            registerService(name);            return true;        } else {            return false;        }    }    @Override    public boolean register(String name, String password) {        Person person = personsMap.get(name);        if (person != null) {   //表中用户名为name的已存在            return false;        } else {            personsMap.put(name, new Person(name, password));            saveData();            return true;        }    }}

(二)实现user.idl中定义的接口

/** * Created by huxijie on 17-5-3. * 实现to-do-list管理user.idl中定义的接口 */public class UserImpl extends UserPOA{    private Date date;    private DateFormat dateFormat;    private String dateRegex;    private List<Item> personalList;                  //单个用户的to-do-list    private Map<String, List<Item>> allPersonListMap;   //所有用户的to-do-list    private ORB orb;    public UserImpl(String name) {        init();        personalList = allPersonListMap.get(name);        if (personalList == null) {            personalList = new ArrayList<Item>();            allPersonListMap.put(name, personalList);        }        date = new Date();        dateFormat = DateFormat.getDateInstance();        //日期格式规定为:xxxx-xx-xx,xx:xx        dateRegex = "\\d{4}-\\d{1,2}-\\d{1,2},\\d{2}:\\d{2}";    }    private void init() {        //从文件中读取to-do-list列表,转化为HashMap        try {            FileInputStream fin = new FileInputStream("item.file");            ObjectInputStream oin = new ObjectInputStream(fin);            try {                Object object = oin.readObject();                allPersonListMap = (HashMap<String, List<Item>>) object;            } catch (ClassNotFoundException e) {                System.out.println("object cast error");                allPersonListMap = new HashMap<String, List<Item>>();            }            oin.close();            fin.close();        } catch (Exception e) {            allPersonListMap = new HashMap<String, List<Item>>();        }    }    public void setORB(ORB orb) {        this.orb = orb;    }    //将to-do-list表保存到本地文件中    private void saveData() {        try {            FileOutputStream fout = new FileOutputStream("item.file");            ObjectOutputStream oout = new ObjectOutputStream(fout);            oout.writeObject(allPersonListMap);            oout.flush();            fout.flush();            oout.close();            fout.close();        } catch (Exception e) {            System.out.println("save error.");            e.printStackTrace();        }    }    //判断输入日期是否符合格式要求    private boolean isFormatMatch(String dateStr) {        return dateStr.matches(dateRegex);    }    //将字符串转化为日期    private Date turnToDate(String dateStr) {        String[] str = dateStr.split("[,|:]");        try {            date = dateFormat.parse(str[0]);            date.setHours(Integer.parseInt(str[1]));            date.setMinutes(Integer.parseInt(str[2]));        } catch (Exception e) {            e.printStackTrace();        }        return date;    }    @Override    public boolean add(String startTime, String endTime, String label) {        Date startDate,endDate;        if (isFormatMatch(startTime) && isFormatMatch(endTime)) {            startDate = turnToDate(startTime);            endDate = turnToDate(endTime);            Item item = new Item(startDate, endDate, label);            personalList.add(item);            saveData();            return true;        } else {            return false;        }    }    @Override    public String query(String startTime, String endTime) {        Date startDate,endDate;        int index = 0;        String queryResult = "";        if (isFormatMatch(startTime) && isFormatMatch(endTime)) {            startDate = turnToDate(startTime);            endDate = turnToDate(endTime);            for (Item item : personalList) {                if (item.getStartTime().after(startDate)                        && item.getEndTime().before(endDate)) {                    index++;                    queryResult += index + " : " + item.getStartTime() +                            "-->" + item.getEndTime() +                            "    " + item.getLabel() + "\n";                }            }        } else {            queryResult = "Date format is wrong!\n";        }        return queryResult;    }    @Override    public String show() {        String result = "";        int index = 0;        if (personalList.size() > 0) {            for (Item item : personalList) {                index++;                result += index + " : " + item.getStartTime() +                        "-->" + item.getEndTime() +                        "    " + item.getLabel() + "\n";            }        } else {            result = "Empty to-do-list!\n";        }        return result;    }    @Override    public boolean delete(String key) {        int index = Integer.parseInt(key);        if (index <= personalList.size() && index >= 1) {            personalList.remove(index - 1);            saveData();            return true;        } else {            return false;        }    }     @Override    public boolean clear() {        int index = personalList.size()-1;        if (index < 0) {            return false;        } else {            while (index >= 0) {                personalList.remove(index);                index--;            }            saveData();            return true;        }    }}

五、基于服务器框架,编写服务对象实现程序

/** * Created by huxijie on 17-5-3. * 基于服务器框架,编写服务器对象 */public class ToDoListServer {    private ORB orb;    private POA rootPOA;    private org.omg.CORBA.Object obj;    private CreatorImpl creatorImpl;    private UserImpl userImpl;    private org.omg.CORBA.Object ref;    private Creator creatorhref;    private User userhref;    private org.omg.CORBA.Object objRef;    private NamingContextExt ncRef;    public static void main(String[] args) {        ToDoListServer toDoListServer = new ToDoListServer();        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.ToDoListServer is ready and waiting....");            //启动线程服务,等待客户端调用            orb.run();        } catch (Exception e) {            e.printStackTrace();        }    }    //对用户名进行注册服务    public void registerUserName(String name) {        try {            //创建一个UserImpl实例            userImpl = new UserImpl(name);            userImpl.setORB(orb);            //从服务中得到对象的引用,并注册到服务中            ref = rootPOA.servant_to_reference(userImpl);            userhref = UserHelper.narrow(ref);            //在命名上下文中绑定这个对象            NameComponent path[] = ncRef.to_name(name);            ncRef.rebind(path, userhref);        } catch (Exception e) {            e.printStackTrace();        }    }}

六、基于客户端存根,编写客户对象调用程序

/** * Created by huxijie on 17-5-3. * 基于客户端存根,编写客户对象调用程序 */public class ToDoListClient {    private Creator creator;    private User user;    private BufferedReader reader;    private ORB orb;    private org.omg.CORBA.Object objRef;    private NamingContextExt ncRef;    public ToDoListClient() {        reader = new BufferedReader(new InputStreamReader(System.in));    }    public static void main(String[] args) {        ToDoListClient toDoListClient = new ToDoListClient();        toDoListClient.init();        toDoListClient.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("Welcome to to_do_list_APP!Please choose:");                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:2017-04-19,08:20):");                                            startTime = reader.readLine();                                            System.out.println("please input endTime (like this:2017-04-19,08:20):");                                            endTime = reader.readLine();                                            System.out.println("please input label:");                                            label = reader.readLine();                                            if (user.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:2017-04-19,08:20):");                                            startTime = reader.readLine();                                            System.out.println("please input endTime (like this:2017-04-19,08:20):");                                            endTime = reader.readLine();                                            System.out.println(user.query(startTime, endTime));                                            break;                                        case "3":                                            System.out.println(user.show());                                            break;                                        case "4":                                            System.out.println("please input index:");                                            index = reader.readLine();                                            if (user.delete(index)) {                                                System.out.println("Delete item successful!");                                            } else {                                                System.out.println("Delete item fail!");                                            }                                            break;                                        case "5":                                            if (user.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类                    user = UserHelper.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;        }    }}

七、启动orbd服务
在shell里输入命令(注意orbd命令是在%JAVA_HOME%/bin下):

orbd -ORBInitialPort 8080 -ORBInitialHost 127.0.0.1

八、启动server
九、启动client

运行结果

一、服务器端
这里写图片描述
二、客户端
这里写图片描述
(一)注册
这里写图片描述
(二)登录
这里写图片描述
(三)Add
这里写图片描述
(四)Show
这里写图片描述
(五)Query
这里写图片描述
(六)Delete
这里写图片描述
(七)Clear
这里写图片描述

代码已放在github上:https://github.com/loveEason/ToDoListApp

0 0
原创粉丝点击