RMI基础
远程方法调用(Remote Method Invocation,RMI)从JDK1.1就已经实现,它大大增强了Java开发分布式应用的能力。可以实现通过网络完成不同JVM间的通信,不仅可以传递基本的数据类型,对象也是可以传递的。RMI是JVM间的通信,如果服务器或客户端不是Java语言开发的,可以考虑web service或者corba。
RMI可以实现调用的透明性及安全性,客户端本身不关心功能是怎么实现的,只需要调用服务器端代码并关心结果即可。功能只限制于服务器端,客户端无法任意进行操作,也提供了安全性。
RMI利用JNDI在服务器端注册客户端需要调用的类。具体的调用是存根和骨架之间完成的,可以看做是客户端和服务器端的代理。
IHello定义了服务器和客户端间通信的接口,客户端只需要调用IHello中的方法即可。IHello需要集成Remote接口,所有方法需要抛出
RemoteException。
/** * 定义一个远程接口,必须继承Remote接口,其中需要远程调用的方法必须抛出RemoteException异常 */ public interface IHello extends Remote { public User user = new User(); public User getUser() throws RemoteException;; public void setUser(User user) throws RemoteException;; /** * 简单的返回“Hello World!"字样 * @return 返回“Hello World!"字样 * @throws java.rmi.RemoteException */ public String helloWorld() throws RemoteException; /** * 一个简单的业务方法,根据传入的人名返回相应的问候语 * @param someBodyName 人名 * @return 返回相应的问候语 * @throws java.rmi.RemoteException */ public String sayHelloToSomeBody() throws RemoteException; }
HelloImpl是服务器端实际实现的方法,客户端通过RMI实际调用的就是HelloImpl。
/** * 远程的接口的实现 */ public class HelloImpl extends UnicastRemoteObject implements IHello { private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } private static final long serialVersionUID = -8403069777370518716L; /** * 因为UnicastRemoteObject的构造方法抛出了RemoteException异常,因此这里默认的构造方法必须写,必须声明抛出RemoteException异常 * @throws RemoteException */ public HelloImpl() throws RemoteException { } /** * 简单的返回“Hello World!"字样 * * @return 返回“Hello World!"字样 * @throws java.rmi.RemoteException */ public String helloWorld() throws RemoteException { return "Hello World!"; } /** * 一个简单的业务方法,根据传入的人名返回相应的问候语 * * @param someBodyName 人名 * @return 返回相应的问候语 * @throws java.rmi.RemoteException */ public String sayHelloToSomeBody() throws RemoteException { return user.getName() + "!"; } }
HelloServer完成的是注册功能,将上面实际工作的HelloImpl进行注册,客户端调用时查找已经注册的HelloImpl实例并调用即可。注册的地址是localhost的8888端口。不同的JVM时将localhost改为具体的IP即可。
/** * 创建RMI注册表,启动RMI服务,并将远程对象注册到RMI注册表中。 */ public class HelloServer { private static User user = new User(); public User getUser() { return user; } public void setUser(User user) { this.user = user; } public static void main(String args[]) { try { //创建一个远程对象 HelloImpl rhello = new HelloImpl(); //本地主机上的远程对象注册表Registry的实例,并指定端口为8888,这一步必不可少(Java默认端口是1099),必不可缺的一步,缺少注册表创建,则无法绑定对象到远程注册表上 LocateRegistry.createRegistry(8888); //把远程对象注册到RMI注册服务器上,并命名为RHello //绑定的URL标准格式为:rmi://host:port/name(其中协议名可以省略,下面两种写法都是正确的) Naming.bind("rmi://localhost:8888/RHello",rhello); // Naming.bind("//localhost:8888/RHello",rhello); System.out.println(">>>>>INFO:远程IHello对象绑定成功!"); } catch (RemoteException e) { System.out.println("创建远程对象发生异常!"); e.printStackTrace(); } catch (AlreadyBoundException e) { System.out.println("发生重复绑定对象异常!"); e.printStackTrace(); } catch (MalformedURLException e) { System.out.println("发生URL畸形异常!"); e.printStackTrace(); } } }
HelloClient模拟了客户端的调用,从localhost的8888端口找到注册的HelloImpl实例并调用。
/** * 客户端测试,在客户端调用远程对象上的远程方法,并返回结果。 */ public class HelloClient { public static void main(String args[]){ try { //在RMI服务注册表中查找名称为RHello的对象,并调用其上的方法 IHello rhello =(IHello) Naming.lookup("rmi://localhost:8888/RHello"); System.out.println(rhello.helloWorld()); User user = new User(); user.setName("inso"); rhello.setUser(user); System.out.println(rhello.sayHelloToSomeBody()); } catch (NotBoundException e) { e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (RemoteException e) { e.printStackTrace(); } } }
User用于客户端调用服务器端代码时传递的参数,说明RMI支持传递对象,需要实现Serializable接口。
public class User implements Serializable{ private static final long serialVersionUID = -4631891643752276172L; private String name; public String getName() { return "user's name is " + name; } public void setName(String name) { this.name = name; } }
先启动HelloServer注册实例,再启动HelloClient进行调用即可看到结果。
还可以将IHello.java,HelloClient.java,User.java拷贝到另外的机器上,模拟客户端实现真正的分布式测试。将服务器端和客户端的localhost改为具体的IP即可。
RMI基础的更多相关文章
- RMI基础篇
远程方法调用(Remote Method Invocation,RMI)从JDK1.1就已经实现,它大大增强了Java开发分布式应用的能力. RMI可以实现通过网络完成不同JVM间的通信,不仅可以传递 ...
- Java RMI之HelloWorld篇
Java RMI 指的是远程方法调用 (Remote Method Invocation).它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法.可以用此方 ...
- JAVA RMI helloworld入门
Java RMI 指的是远程方法调用 (Remote Method Invocation).它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法.可以用此方 ...
- java的RMI(Remote Method Invocation)
RMI 相关知识RMI全称是Remote Method Invocation-远程方法调用,Java RMI在JDK1.1中实现的,其威力就体现在它强大的开发分布式网络应用的能力上,是纯Java的网络 ...
- Java RMI 远程方法调用
Java RMI 指的是远程方法调用 (Remote Method Invocation).它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法.可以用此方 ...
- Java远程方法调用(RMI)
Java RMI 指的是远程方法调用 (Remote Method Invocation).它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法.可以用此方 ...
- Java RMI简单例子HelloWorld
Java RMI 指的是远程方法调用 (Remote Method Invocation).它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法.可以用此方 ...
- Java RMI 框架_远程方法调用(2016-08-16)
概念: Java RMI 指的是远程方法调用 (Remote Method Invocation).它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法.可 ...
- 【Socket】Java Socket基础编程
Socket是Java网络编程的基础,了解还是有好处的, 这篇文章主要讲解Socket的基础编程.Socket用在哪呢,主要用在进程间,网络间通信.本篇比较长,特别做了个目录: 一.Socket通信基 ...
随机推荐
- A very hard Aoshu problem(dfs或者数位)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4403 A very hard Aoshu problem Time Limit: 2000/1000 ...
- 解决vi编辑器不能使用方向键和退格键问题的两种方法
方法1.使用vi命令时,不能正常编辑文件,使用方向键时老是出现很多字母? 在Ubuntu中,进入vi命令的编辑模式,发现按方向键不能移动光标,而是会输出ABCD,以及退格键也不能正常删除字符.这是由于 ...
- TCP为什么需要3次握手与4次挥手(转载)
为什么需要“三次握手” 在谢希仁著<计算机网络>第四版中讲“三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”.在另一部经典的<计算机网络> ...
- Spark学习笔记1(初始spark
1.什么是spark? spark是一个基于内存的,分布式的,大数据的计算框架,可以解决各种大数据领域的计算问题,提供了一站式的服务 Spark2009年诞生于伯克利大学的AMPLab实验室 2010 ...
- [国嵌攻略][154][Linux-I2C子系统]
IIC子系统架构 device driver层: 1.device driver,由用户开发. 2.i2c-dev由内核实现,但是需要配合应用模式驱动才能使用. i2c core层: 1.总线驱动,也 ...
- Caused by: java.sql.SQLException: Couldn't perform the operation getAutoCommit: You can't perform any operations on this connection. It has been automatically closed by Proxool for some reason (see lo
系统启动,一段时间不操作,然后在来操作时,报错如下: Caused by: java.sql.SQLException: Couldn't perform the operation getAutoC ...
- 番外篇--Moddule Zero安装
Moddule Zero 安装 1.2.1 从模板创建 使用ABP和module-zero开始一个新项目最简单的方式是使用启动模板.详细了解请参考启动模板文档. 1.2.2 手动安装 如果你有一个预先 ...
- 为什么要进行URL编码
我们都知道Http协议中参数的传输是"key=value"这种简直对形式的,如果要传多个参数就需要用“&”符号对键值对进行分割.如"?name1=value1&a ...
- eclipse导入web项目变成java项目解决办法
右键工程,properties-> Project Facets-> 点convert to faceted..连接 -> 把Dynamic Web Moudle勾上
- 在eclipse中创建maven webapp项目时弹出错误-解决办法
在eclipse中创建maven webapp项目时报错: Could not resolve archetype org.apache.maven.archetypes:maven-archetyp ...