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),如果你有任何问题的话,请给我留言。

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

博采众生

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

博采众生

Eclipse中的结构

博采众生

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

博采众生

客户端启动配置

博采众生

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

博采众生

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

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

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

 

  1. packagenet.csdn.blog.qb2049_xg;
  2. importjava.rmi.Remote;
  3. importjava.rmi.RemoteException;
  4. /**
  5. *AllCalculate.java
  6. *@authorUlyssesMa
  7. *@date2008-9-9
  8. *Remote在这里标识远程对象
  9. */
  10. publicinterfaceAllCalculateextendsRemote
  11. {
  12. //加
  13. publicfloatadd(floata,floatb)throwsRemoteException;
  14. //减
  15. publicfloatminus(floata,floatb)throwsRemoteException;
  16. //除
  17. publicfloatdiv(floata,floatb)throwsRemoteException;
  18. //乘
  19. publicfloatmul(floata,floatb)throwsRemoteException;
  20. }

*****************************************************************************

 

 

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

************************************************************************************

 

 

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

 

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

阅读更多
文章热词
换一批

没有更多推荐了,返回首页