Java基础中的RMI教程

RMI基础

远程方法调用(Remote Method Invocation,RMI)从JDK1.1就已经实现,它大大增强了Java开发分布式应用的能力。可以实现通过网络完成不同JVM间的通信,不仅可以传递基本的数据类型,对象也是可以传递的。RMI是JVM间的通信,如果服务器或客户端不是Java语言开发的,可以考虑web service或者corba。

  RMI可以实现调用的透明性及安全性,客户端本身不关心功能是怎么实现的,只需要调用服务器端代码并关心结果即可。功能只限制于服务器端,客户端无法任意进行操作,也提供了安全性。

 ![](https://images0.cnblogs.com/i/623461/201408/032251263683680.jpg)

  RMI利用JNDI在服务器端注册客户端需要调用的类。具体的调用是存根和骨架之间完成的,可以看做是客户端和服务器端的代理。

IHello定义了服务器和客户端间通信的接口,客户端只需要调用IHello中的方法即可。IHello需要集成Remote接口,所有方法需要抛出

RemoteException。

1/** * 定义一个远程接口,必须继承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。

1/** * 远程的接口的实现 */ 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即可。

1/** * 创建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实例并调用。

1/** * 客户端测试,在客户端调用远程对象上的远程方法,并返回结果。 */ 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接口。

1public 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即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值