1.创建接口,继续Remote接口
package com.rmi.server; import java.rmi.Remote; import java.rmi.RemoteException; import java.util.Date; public interface HelloService extends Remote { public String echo(String msg) throws RemoteException; public Date getDate() throws RemoteException; }
2.创建服务类,继续Remote接口
package com.rmi.server; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; import java.util.Date; public class HelloServiceImpl extends UnicastRemoteObject implements HelloService { private static final long serialVersionUID = 1L; String name; protected HelloServiceImpl(String name) throws RemoteException { this.name = name; } @Override public String echo(String msg) throws RemoteException { System.out.println(name + ":调用echo()方法"); return "echo:" + msg + " from " + name; } @Override public Date getDate() throws RemoteException { System.out.println(name + ":调用getDate()方法"); return new Date(); } }
3.绑定服务
package com.rmi.server; import java.rmi.registry.LocateRegistry; import javax.naming.Context; import javax.naming.InitialContext; public class SimpleServer { public static void main(String[] args) { try { HelloService service1 = new HelloServiceImpl("service1"); HelloService service2 = new HelloServiceImpl("service2"); Context namingContext = new InitialContext(); // 之前一直报javax.naming.ServiceUnavailableException,加上此方法后才正常 LocateRegistry.createRegistry(1099); namingContext.rebind("rmi://127.0.0.1:1099/HelloService1", service1); namingContext.rebind("rmi://127.0.0.1:1099/HelloService2", service2); System.out.println("服务器启动..."); } catch (Exception e) { e.printStackTrace(); } } }
4.客户端调用
package com.rmi.client; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NameClassPair; import javax.naming.NamingEnumeration; import com.rmi.server.HelloService; public class SimpleClient { public static void showRemoteObjects(Context namingContext) throws Exception { NamingEnumeration<NameClassPair> e = namingContext.list("rmi:"); while (e.hasMore()) { System.out.println(e.next().getName()); } } public static void main(String[] args) { String url = "rmi://127.0.0.1:1099/"; try { Context namingContext = new InitialContext(); HelloService service1 = (HelloService) namingContext.lookup(url + "HelloService1"); HelloService service2 = (HelloService) namingContext.lookup(url + "HelloService2"); Class stubClass = service1.getClass(); System.out.println("service1 是" + stubClass.getName() + "的实例"); Class[] interfaces = stubClass.getInterfaces(); for (int i = 0; i < interfaces.length; i++) { System.out.println("存根类实现了" + interfaces[i].getName() + "接口"); } System.out.println(service1.echo("测试")); System.out.println(service1.getDate()); System.out.println(service2.echo("测试2")); System.out.println(service2.getDate()); showRemoteObjects(namingContext); } catch (Exception e) { e.printStackTrace(); } } }
5.输出
服务端:
服务器启动... service1:调用echo()方法 service1:调用getDate()方法 service2:调用echo()方法 service2:调用getDate()方法
客户端:
service1 是$Proxy0的实例 存根类实现了java.rmi.Remote接口 存根类实现了com.rmi.server.HelloService接口 echo:测试 from service1 Tue Jul 29 16:14:34 CST 2014 echo:测试2 from service2 Tue Jul 29 16:14:34 CST 2014 HelloService1 HelloService2
6.LocateRegistry.createRegistry(int port)
java.rmi包中提供了类java.rmi.registry.LocateRegistry,用于获取名字服务或创建名字服务.调用LocateRegistry.createRegistry(int port)方法可以在某一特定端口创建名字服务,从而用户无需再手工启动rmiregistry.此外,LocateRegistry.getRegistry(String host,int port)方法可用于获取名字服务.
如果不写LocateRegistry.createRegistry(int port),也可以运行命令start rmiregistry [port]启动注册表,默认1099端口