RMI原理展示-UI含源代码

博采众生我在上一篇文章中,简单地介绍了RMI的原理,这一篇文章我想在通过一个稍微复杂一点的例子,更好的向大家说明。读这篇文章需要你先参考我的上一篇文章: RMI(Remote Method Invocation)原理浅析。

例子中,用到了javaUI的swing和事件处理,以及线程知识,如果你对这方面的知识不是太清楚的话,希望你能参考一下资料,非常简单 !

例子的思想就是通过在远程启动服务,客户端提交任务,处理完以后,把结果反馈给客户端完成任务。程序的功能就是计算加减乘除, 有六个文件,分别为:

AllCalculate.java,接口,定义了客户端和服务端共用的接口; AllCalculateImpl.java,服务端接口实现; AllCalculateServer.java,服务端服务提供者,它需要实例接口实现,导入到注册表中; MyRMIExam.java,客户端启动 MyRMIGui.java,客户端UI,实现了加减乘除,分别在不同的线程里处理,是程序不会猛然间显得没有反应; ServiceListFrame.java,使用在客户端,用以检索服务端机器的远程服务名字。

tools包是我自己写的一个工具包,辅助我来验证客户的输入,有关这个包中的文本验证和窗体居中显示,请你参考我的三片文章: 文本控件内容录入限制(含源代码说明)(一), Java 文本控件内容录入限制(含源代码说明)(二), Java窗体居中显示。由于源代码比较长,在这里就是简单的罗列了: AllCalculate.java,AllCalculateServer.java和MyRMIExam.java代码清单,如果你需要参考完整的源代码,请你到CSDN资源下载中心下载,文件名称为:MyRMI.rar(搜索下载, 我得源代码中使用的UTF-8的编码格式,工程是Eclipse),如果你有任何问题的话,请给我留言。

下面是程序运行的几幅演示图片,你可以在你的电脑上演示:

RMI原理展示-UI含源代码_第1张图片

所在环境的文件结构,方便你的实验

RMI原理展示-UI含源代码_第2张图片

Eclipse中的结构

RMI原理展示-UI含源代码_第3张图片

在Eclipse中启动设置,注意此时需要先启动rmiregistry服务环境

RMI原理展示-UI含源代码_第4张图片

客户端启动配置

RMI原理展示-UI含源代码_第5张图片

如果你没有安装Eclipse,需要手动命令行启动

RMI原理展示-UI含源代码_第6张图片

命令行启动客户端,注意此时client.policy放在exam目录下

图片中,小三角加感叹号是由于我使用恶java的SecurityManager,你可以在源代码中注释掉这个功能。

以下是几个程序源码清单:

  1. package net.csdn.blog.qb2049_xg;
  2. import java.rmi.Remote;
  3. import java.rmi.RemoteException;
  4. /**
  5.  *AllCalculate.java
  6.  * @author Ulysses Ma
  7.  * @date 2008-9-9
  8.  *Remote 在这里标识远程对象
  9.  */
  10. public interface AllCalculate extends Remote 
  11. {
  12.     //加
  13.     public float add(float a,float b) throws RemoteException;
  14.     //减
  15.     public float minus(float a,float b) throws RemoteException;
  16.     //除
  17.     public float div(float a,float b) throws RemoteException;
  18.     //乘
  19.     public float mul(float a,float b) throws RemoteException;  
  20. }
*****************************************************************************

  1. package net.csdn.blog.qb2049_xg;
  2. import java.rmi.AccessException;
  3. import java.rmi.AlreadyBoundException;
  4. import java.rmi.RemoteException;
  5. import java.rmi.registry.LocateRegistry;
  6. import java.rmi.registry.Registry;
  7. /**
  8.  * AllCalculateServer.java
  9.  * @author Ulysses Ma
  10.  * @date 2008-9-9
  11.  */
  12. public class AllCalculateServer {
  13.     public static void main(String[] args) {
  14.        try{
  15.             //实现要导出的远程对象,它来完成运算(创建远程对象实例)
  16.             AllCalculateImpl allCalculate=new AllCalculateImpl();
  17.             //获得本地的(RMI,要求是在rmiregistry启动情况下)注册表
  18.             Registry rg=LocateRegistry.getRegistry();
  19.             //实现对象的绑定,完成远程对象的注册工作
  20.             rg.bind("allCalculate1", allCalculate);
  21.             //状态提示
  22.             System.out.println("实现所有方法的服务现在已成功启动!");
  23.        }catch(NullPointerException ne){
  24.            System.out.println("服务端出现了异常,可能是bind方法中name或是对象为空。/n"+ne.getMessage());
  25.        }catch(AlreadyBoundException abe){
  26.            System.out.println("服务端出现了异常,可能是bind名字已被占用。/n"+abe.getMessage());
  27.        }catch(AccessException ae){
  28.            System.out.println("服务端出现了异常,可能是访问被拒绝。/n"+ae.getMessage());
  29.        }catch(RemoteException re){
  30.         System.out.println("服务端出现了异常,可能是连接通信出现了问题。/n"+re.getMessage());
  31.        }        
  32.     }
  33. }
************************************************************************************

  1. package net.csdn.blog.qb2049_xg;
  2. import java.awt.BorderLayout;
  3. import java.awt.Color;
  4. import java.awt.Container;
  5. import java.awt.GridBagConstraints;
  6. import java.awt.GridBagLayout;
  7. import java.awt.event.ActionEvent;
  8. import java.awt.event.ActionListener;
  9. import java.rmi.NotBoundException;
  10. import java.rmi.RemoteException;
  11. import java.rmi.registry.LocateRegistry;
  12. import java.rmi.registry.Registry;
  13. import javax.swing.JButton;
  14. import javax.swing.JFrame;
  15. import javax.swing.JLabel;
  16. import javax.swing.JMenu;
  17. import javax.swing.JMenuBar;
  18. import javax.swing.JMenuItem;
  19. import javax.swing.JOptionPane;
  20. import javax.swing.JPanel;
  21. import javax.swing.JScrollPane;
  22. import javax.swing.JTextArea;
  23. import javax.swing.JTextField;
  24. import javax.swing.border.LineBorder;
  25. import net.csdn.blog.qb2049_xg.tools.JTextHelp;
  26. import net.csdn.blog.qb2049_xg.tools.MidScr;
  27. /**
  28.  * MyRMIGui.java
  29.  * @author Ulysses Ma
  30.  *
  31.  */
  32. public class MyRMIGui extends JFrame implements ActionListener
  33. {
  34.     //序列化标识使用
  35.     private static final long serialVersionUID = 2049L;
  36.     //窗体布局面板的定义
  37.     private JPanel title_p=new JPanel();
  38.     private JPanel body_p=new JPanel();
  39.     private JPanel bottom_p=new JPanel();
  40.     private JTextField addA_t,addB_t,minusA_t,minusB_t,divA_t,divB_t,mulA_t,mulB_t;
  41.     private JTextField addResult_t,addServer_t,minusResult_t,minusServer_t,divResult_t,
  42.               divServer_t,mulResult_t,mulServer_t,serviceAdd_t,serviceMinus_t,serviceMul_t,serviceDiv_t;
  43.     //分
  44.     private ServiceListFrame listFrame;
  45.     //一些关键性部件声明
  46.     private JLabel title_l=new JLabel("RMI 加、减、乘、除实验");
  47.     private JLabel exception_l=new JLabel("异常处理:");
  48.     private JTextArea exception_ta=new JTextArea(10,70);
  49.     //构造函数
  50.     public MyRMIGui() 
  51.     {
  52.       //标题部分显示的设置
  53.       title_p.setAlignmentX(JPanel.CENTER_ALIGNMENT);
  54.       title_p.add(title_l);
  55.       
  56.       //主体部分的设置      
  57.       GridBagLayout gbl1=new GridBagLayout();
  58.       body_p.setLayout(gbl1);
  59.       GridBagConstraints c1 = new GridBagConstraints();
  60.       
  61.       //表题说明
  62.       JLabel numberA,numberB,result,equal,operate,server,start,service;
  63.       numberA=new JLabel("数A");
  64.       numberA.setHorizontalAlignment(JLabel.CENTER);
  65.       numberB=new JLabel("数B");
  66.       numberB.setHorizontalAlignment(JLabel.CENTER);
  67.       result=new JLabel("结果");
  68.       result.setHorizontalAlignment(JLabel.CENTER);
  69.       equal=new JLabel("等号");
  70.       equal.setHorizontalAlignment(JLabel.CENTER);
  71.       operate=new JLabel("操作符");
  72.       operate.setHorizontalAlignment(JLabel.CENTER);
  73.       server=new JLabel("服务器");
  74.       server.setHorizontalAlignment(JLabel.CENTER);
  75.       service=new JLabel("服务名称");
  76.       service.setHorizontalAlignment(JLabel.CENTER);
  77.       start=new JLabel("开始");
  78.       start.setHorizontalAlignment(JLabel.CENTER);
  79.       c1.fill=GridBagConstraints.VERTICAL;
  80.       c1.gridx=0;
  81.       c1.gridy=0;
  82.       body_p.add(numberA,c1);
  83.       c1.gridx=1;
  84.       body_p.add(operate,c1);
  85.       c1.gridx=2;
  86.       body_p.add(numberB,c1);
  87.       c1.gridx=3;
  88.       body_p.add(equal,c1);
  89.       c1.gridx=4;
  90.       body_p.add(result,c1);
  91.       c1.gridx=5;
  92.       body_p.add(server,c1);
  93.       c1.gridx=6;
  94.       body_p.add(service,c1);
  95.       c1.gridx=7;
  96.       body_p.add(start,c1);
  97.       
  98.      //加运算UI
  99.       addA_t=new JTextField(10);
  100.       addB_t=new JTextField(10);
  101.       new JTextHelp(addA_t,JTextHelp.NUMBER).insertCheck();
  102.       new JTextHelp(addB_t,JTextHelp.NUMBER).insertCheck();
  103.       addResult_t=new JTextField(10);
  104.       serviceAdd_t=new JTextField(10);
  105.       addServer_t=new JTextField(15);
  106.       JButton addStart_b=new JButton("开始计算");
  107.       addStart_b.addActionListener(this);
  108.       addStart_b.setActionCommand("add");
  109.       JLabel add_l=new JLabel("+");
  110.       add_l.setHorizontalAlignment(JLabel.CENTER);
  111.       JLabel addEqual_l=new JLabel("=");
  112.       addEqual_l.setHorizontalAlignment(JLabel.CENTER);
  113.       c1.gridx=0;
  114.       c1.gridy=1;
  115.       body_p.add(addA_t,c1);
  116.       c1.gridx=1;
  117.       body_p.add(add_l,c1);
  118.       c1.gridx=2;
  119.       body_p.add(addB_t,c1);
  120.       c1.gridx=3;
  121.       body_p.add(addEqual_l,c1);
  122.       c1.gridx=4;
  123.       body_p.add(addResult_t,c1);
  124.       c1.gridx=5;
  125.       body_p.add(addServer_t,c1);
  126.       c1.gridx=6;
  127.       body_p.add(serviceAdd_t,c1);
  128.       c1.gridx=7;
  129.       body_p.add(addStart_b,c1);
  130.       
  131.       //减运算UI
  132.       minusA_t=new JTextField(10);
  133.       minusB_t=new JTextField(10);
  134.       new JTextHelp(minusA_t,JTextHelp.NUMBER).insertCheck();
  135.       new JTextHelp(minusB_t,JTextHelp.NUMBER).insertCheck();
  136.       minusResult_t=new JTextField(10);
  137.       minusServer_t=new JTextField(15);
  138.       serviceMinus_t=new JTextField(10);
  139.       JButton minusStart_b=new JButton("开始计算");
  140.       minusStart_b.addActionListener(this);
  141.       minusStart_b.setActionCommand("minus");
  142.       JLabel minus_l=new JLabel("-");
  143.       minus_l.setHorizontalAlignment(JLabel.CENTER);
  144.       JLabel minusEqual_l=new JLabel("=");
  145.       minusEqual_l.setHorizontalAlignment(JLabel.CENTER);
  146.       c1.gridx=0;
  147.       c1.gridy=2;
  148.       body_p.add(minusA_t,c1);
  149.       c1.gridx=1;
  150.       body_p.add(minus_l,c1);
  151.       c1.gridx=2;
  152.       body_p.add(minusB_t,c1);
  153.       c1.gridx=3;
  154.       body_p.add(minusEqual_l,c1);
  155.       c1.gridx=4;
  156.       body_p.add(minusResult_t,c1);
  157.       c1.gridx=5;
  158.       body_p.add(minusServer_t,c1);
  159.       c1.gridx=6;
  160.       body_p.add(serviceMinus_t,c1);
  161.       c1.gridx=7;
  162.       body_p.add(minusStart_b,c1);
  163.       
  164.       //除运算UI
  165.       divA_t=new JTextField(10);
  166.       divB_t=new JTextField(10);
  167.       new JTextHelp(divA_t,JTextHelp.NUMBER).insertCheck();
  168.       new JTextHelp(divB_t,JTextHelp.NUMBER).insertCheck();
  169.       divResult_t=new JTextField(10);
  170.       divServer_t=new JTextField(15);
  171.       serviceDiv_t=new JTextField(10);
  172.       JButton divStart_b=new JButton("开始计算");
  173.       divStart_b.setActionCommand("div");
  174.       divStart_b.addActionListener(this);
  175.       JLabel div_l=new JLabel("÷");
  176.       div_l.setHorizontalAlignment(JLabel.CENTER);
  177.       JLabel divEqual_l=new JLabel("=");
  178.       divEqual_l.setHorizontalAlignment(JLabel.CENTER);
  179.       c1.gridx=0;
  180.       c1.gridy=3;
  181.       body_p.add(divA_t,c1);
  182.       c1.gridx=1;
  183.       body_p.add(div_l,c1);
  184.       c1.gridx=2;
  185.       body_p.add(divB_t,c1);
  186.       c1.gridx=3;
  187.       body_p.add(divEqual_l,c1);
  188.       c1.gridx=4;
  189.       body_p.add(divResult_t,c1);
  190.       c1.gridx=5;
  191.       body_p.add(divServer_t,c1);
  192.       c1.gridx=6;
  193.       body_p.add(serviceDiv_t,c1);
  194.       c1.gridx=7;
  195.       body_p.add(divStart_b,c1);
  196.       
  197.      //乘运算UI
  198.       mulA_t=new JTextField(10);
  199.       mulB_t=new JTextField(10);
  200.       new JTextHelp(mulA_t,JTextHelp.NUMBER).insertCheck();
  201.       new JTextHelp(mulB_t,JTextHelp.NUMBER).insertCheck();
  202.       mulResult_t=new JTextField(10);
  203.       mulServer_t=new JTextField(15);
  204.       serviceMul_t=new JTextField(10);
  205.       JButton mulStart_b=new JButton("开始计算");
  206.       mulStart_b.addActionListener(this);
  207.       mulStart_b.setActionCommand("mul");
  208.       JLabel mul_l=new JLabel("×");
  209.       mul_l.setHorizontalAlignment(JLabel.CENTER);
  210.       JLabel mulEqual_l=new JLabel("=");
  211.       mulEqual_l.setHorizontalAlignment(JLabel.CENTER);
  212.       c1.gridx=0;
  213.       c1.gridy=4;
  214.       body_p.add(mulA_t,c1);
  215.       c1.gridx=1;
  216.       body_p.add(mul_l,c1);
  217.       c1.gridx=2;
  218.       body_p.add(mulB_t,c1);
  219.       c1.gridx=3;
  220.       body_p.add(mulEqual_l,c1);
  221.       c1.gridx=4;
  222.       body_p.add(mulResult_t,c1);
  223.       c1.gridx=5;
  224.       body_p.add(mulServer_t,c1);
  225.       c1.gridx=6;
  226.       body_p.add(serviceMul_t,c1);
  227.       c1.gridx=7;
  228.       body_p.add(mulStart_b,c1);
  229.       
  230.       //状态初始化
  231.       addResult_t.setEditable(false);
  232.       minusResult_t.setEditable(false);
  233.       mulResult_t.setEditable(false);
  234.       divResult_t.setEditable(false);
  235.       
  236.       //异常问题的处理
  237.       GridBagLayout gbl=new GridBagLayout();
  238.       bottom_p.setLayout(gbl);
  239.       GridBagConstraints c = new GridBagConstraints();
  240.       c.fill=GridBagConstraints.NONE;
  241.       c.gridx=0;
  242.       c.gridy=0;
  243.       bottom_p.add(exception_l,c);
  244.       c.gridx=5;
  245.       JButton clear_b=new JButton("清空");
  246.       clear_b.addActionListener(this);  
  247.       clear_b.setActionCommand("clear");
  248.       bottom_p.add(clear_b,c);
  249.       
  250.       exception_ta.setBorder(new LineBorder(new Color(0,0,0)));
  251.       exception_ta.setLineWrap(true);
  252.       JScrollPane scrollPane=new JScrollPane(exception_ta);
  253.       c.fill=GridBagConstraints.HORIZONTAL;
  254.       c.gridx=0;
  255.       c.gridy=1;
  256.       c.gridwidth=6;
  257.       bottom_p.add(scrollPane,c);   
  258.       
  259.       //设置菜单栏
  260.       JMenuBar jmb=new JMenuBar();
  261.       JMenu help_m=new JMenu("帮助");
  262.       JMenuItem listService=new JMenuItem("浏览已注册的服务");
  263.       listService.addActionListener(this);
  264.       listService.setActionCommand("list");
  265.       JMenuItem exit=new JMenuItem("退出");
  266.       exit.addActionListener(this);
  267.       exit.setActionCommand("exit");
  268.       help_m.add(listService);
  269.       help_m.add(exit);
  270.       jmb.add(help_m);
  271.       
  272.       //加载面板
  273.       this.setJMenuBar(jmb);
  274.       Container rp=this.getContentPane();      
  275.       rp.add(title_p,BorderLayout.NORTH);
  276.       rp.add(body_p,BorderLayout.CENTER);
  277.       rp.add(bottom_p,BorderLayout.SOUTH);
  278.       
  279.       
  280.       
  281.       //设置窗体展示宽度
  282.       this.setSize(800,450);
  283.       //设置显示位置
  284.       MidScr ms=new MidScr(this);
  285.       this.setLocation(ms.getX(),ms.getY());
  286.       //设置标题
  287.       this.setTitle("测试Java RMI的使用问题");
  288.       //关闭点击后的处理
  289.       this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  290.       this.setVisible(true);      
  291.       this.validate();
  292.     }
  293.    //事件的处理
  294.     public void actionPerformed(ActionEvent e)
  295.     {
  296.         //add,minus,div,mul   commands
  297.         
  298.         exception_ta.setForeground(new Color(255,0,0));
  299.         //加事件的处理
  300.         if(e.getActionCommand().equals("add"))
  301.         {
  302.             String arg1=addA_t.getText().trim();
  303.             String arg2=addB_t.getText().trim();
  304.             String host=addServer_t.getText().trim();
  305.             String service=serviceAdd_t.getText().trim();
  306.             if(arg1.equals("")&&arg2.equals(""))
  307.             {
  308.                 JOptionPane.showMessageDialog(this,"参与计算的两个数字不能为空,请检查你的输入,谢谢!",
  309.                                    "远程调用",JOptionPane.INFORMATION_MESSAGE);
  310.                 return ;
  311.             }   
  312.             new Thread(new LoadRMI(host,arg1,arg2,service,e.getActionCommand())).start();
  313.         }
  314.         //减事件的处理
  315.         if(e.getActionCommand().equals("minus"))
  316.         {
  317.             String arg1=minusA_t.getText().trim();
  318.             String arg2=minusB_t.getText().trim();
  319.             String host=minusServer_t.getText().trim();
  320.             String service=serviceMinus_t.getText().trim();
  321.             if(arg1.equals("")&&arg2.equals(""))
  322.             {
  323.                 JOptionPane.showMessageDialog(this,"参与计算的两个数字不能为空,请检查你的输入,谢谢!",
  324.                                    "远程调用",JOptionPane.INFORMATION_MESSAGE);
  325.                 return ;
  326.             }   
  327.             new Thread(new LoadRMI(host,arg1,arg2,service,e.getActionCommand())).start();
  328.         }
  329.         //乘事件的处理
  330.         if(e.getActionCommand().equals("mul"))
  331.         {
  332.             String arg1=mulA_t.getText().trim();
  333.             String arg2=mulB_t.getText().trim();
  334.             String host=mulServer_t.getText().trim();
  335.             String service=serviceMul_t.getText().trim();
  336.             if(arg1.equals("")&&arg2.equals(""))
  337.             {
  338.                 JOptionPane.showMessageDialog(this,"参与计算的两个数字不能为空,请检查你的输入,谢谢!",
  339.                                    "远程调用",JOptionPane.INFORMATION_MESSAGE);
  340.                 return ;
  341.             }   
  342.             new Thread(new LoadRMI(host,arg1,arg2,service,e.getActionCommand())).start();   
  343.         }
  344.         //除事件的处理
  345.         if(e.getActionCommand().equals("div"))
  346.         {
  347.             String arg1=divA_t.getText().trim();
  348.             String arg2=divB_t.getText().trim();
  349.             String host=divServer_t.getText().trim();
  350.             String service=serviceDiv_t.getText().trim();
  351.             if(arg1.equals("")&&arg2.equals(""))
  352.             {
  353.                 JOptionPane.showMessageDialog(this,"参与计算的两个数字不能为空,请检查你的输入,谢谢!",
  354.                                    "远程调用",JOptionPane.INFORMATION_MESSAGE);
  355.                 return ;
  356.             }   
  357.             new Thread(new LoadRMI(host,arg1,arg2,service,e.getActionCommand())).start();
  358.         }
  359.         //清理文本框按钮事件
  360.         if(e.getActionCommand().equals("clear")){
  361.             exception_ta.setText("");
  362.         }
  363.         //退出菜单事件处理
  364.         if(e.getActionCommand().equals("exit")){
  365.             System.exit(HIDE_ON_CLOSE);
  366.         }
  367.         //查看注册服务菜单事件
  368.         if(e.getActionCommand().equals("list")){
  369.             if(listFrame==null)
  370.                listFrame=new ServiceListFrame();
  371.             else
  372.                 listFrame.setVisible(true);
  373.         }
  374.         
  375.     }   
  376.     //完成各种方法调用,在这里使用了多线程的方法,可以多个任务同时的进行,不会有等待的感觉
  377.     class LoadRMI implements Runnable
  378.     {
  379.         String host,arg1,arg2,service;
  380.         String actionCommand;
  381.         public LoadRMI(String host,String arg1,String arg2,String service,String actionCommand){
  382.             this.arg1=arg1;
  383.             this.arg2=arg2;
  384.             this.host=host;
  385.             this.service=service;
  386.             this.actionCommand=actionCommand;           
  387.         }
  388.         public void run(){
  389.             try{
  390.                 //如果host的值是null的话,那么系统就默认调用本地远程方法 
  391.                 Registry rg=LocateRegistry.getRegistry(host);
  392.                 AllCalculate ac=(AllCalculate)rg.lookup(service);
  393.                 float a=Float.valueOf(arg1).floatValue();
  394.                 float b=Float.valueOf(arg2).floatValue();
  395.                 //根据事件名称调用方法
  396.                 if(this.actionCommand.equals("add")){
  397.                     addResult_t.setText(String.valueOf(ac.add(a, b)));
  398.                 }
  399.                 if(this.actionCommand.equals("minus")){
  400.                     minusResult_t.setText(String.valueOf(ac.minus(a, b)));
  401.                 }
  402.                 if(this.actionCommand.equals("mul")){
  403.                     mulResult_t.setText(String.valueOf(ac.mul(a, b)));
  404.                 }
  405.                 if(this.actionCommand.equals("div")){
  406.                     divResult_t.setText(String.valueOf(ac.div(a, b)));
  407.                 }
  408.             }catch(NullPointerException npe){
  409.                 exception_ta.append("调用的服务名称为空"+npe.getMessage()+"/n");
  410.             }catch(NotBoundException nbe){
  411.                 exception_ta.append("调用的服务不存在,请检查你的输入"+nbe.getMessage()+"/n");
  412.             }   
  413.             catch(RemoteException re){
  414.                 exception_ta.append("调用远程方法时出现了问题,情况可能是:"+re.getMessage()+"/n");
  415.             }
  416.         }
  417.     }
  418. }

如果你对这个小例子感兴趣的话,请你到CSDN资源中心下载!

你可能感兴趣的:(RMI原理展示-UI含源代码)