rmi spring

来源:互联网 发布:115网盘淘宝怎么搜 编辑:程序博客网 时间:2024/04/29 14:22
传统的实现RMI,需要
1.服务接口必须从Remote派生,每个方法抛出RemoteException
2.实现类必须从UnicastRemoteObject派生
3.所有方法的参数和返回值,必须是基本类型,或者实现了Serializable接口

Java代码 复制代码 收藏代码
  1. public class User implements Serializable {  
  2.   private String username;  
  3.   private String password;  
  4.   public User(String username, String password) {  
  5.     this.username = username;  
  6.     this.password = password;  
  7.   }  
  8.   public String getUsername() {  
  9.     return username;  
  10.   }  
  11.   public String getPassword() {  
  12.     return password;  
  13.   }  
  14. }  
  15. public interface RmiUserService extends Remote {  
  16.   User login(String username, String password) throws RemoteException;  
  17.   void create(String username, String password) throws RemoteException;  
  18. }  
  19. public class RmiUserServiceImpl extends UnicastRemoteObject implements RmiUserService {  
  20.   protected RmiUserServiceImpl() throws RemoteException {  
  21.   }  
  22.   private Map<String, String> users = new HashMap<String, String>();  
  23.   public void create(String username, String password) {  
  24.     if (username == null || password == null)  
  25.       throw new IllegalArgumentException("Invalid args.");  
  26.     if (users.get(username) != null)  
  27.       throw new RuntimeException("User exist!");  
  28.     users.put(username, password);  
  29.   }  
  30.   public User login(String username, String password) {  
  31.     if (username == null || password == null)  
  32.       throw new IllegalArgumentException("Invalid args.");  
  33.     if (password.equals(users.get(username)))  
  34.       return new User(username, password);  
  35.     throw new RuntimeException("Login failed.");  
  36.   }  
  37.   public static void main(String[] args) throws RemoteException, MalformedURLException, AlreadyBoundException {  
  38.     LocateRegistry.createRegistry(1099);  
  39.     Naming.bind("rmi://localhost:1099/UserService"new RmiUserServiceImpl());  
  40.   }  
  41. }  
  42. public class Client {  
  43.   public static void main(String[] args) throws RemoteException, MalformedURLException, NotBoundException {  
  44.     RmiUserService service = (RmiUserService) Naming.lookup("rmi://localhost:1099/UserService");  
  45.     service.create("xace""1");  
  46.     System.out.println(service.login("xace""1"));  
  47.   }  
  48. }  
  49.   
  50. 调用:  
  51. >rmic RmiUserServiceImpl  
  52. >java Client  



Spring对RMI提供的支持
不用写一行代码,直接在Spring的配置文件中声明,就可以将一个传统的java类作为RMI服务输出
Xml代码 复制代码 收藏代码
  1. <bean id="userService" class="example.rmi.UserServiceImpl" />  
  2.   
  3. <bean id="rmiService" class="org.springframework.remoting.rmi.RmiServiceExporter">  
  4.   <property name="serviceName" value="UserService"/>  
  5.   <property name="service" ref="userService"/>  
  6.   <property name="serviceInterface" value="example.rmi.UserService"/>  
  7.   <property name="registryPort" value="1099"/>  
  8. </bean>  


唯一编写的代码是main()方法,启动Spring容器
Java代码 复制代码 收藏代码
  1. public static void main(String[] args) {  
  2.     new ClassPathXmlApplicationContext("config.xml");  
  3. }  

客户端代码
Java代码 复制代码 收藏代码
  1. public class Client {  
  2.   public static void main(String[] args) throws Exception {  
  3.     RmiProxyFactoryBean factory = new RmiProxyFactoryBean();  
  4.     factory.setServiceInterface(UserService.class);  
  5.     factory.setServiceUrl("rmi://localhost:1099/UserService");  
  6.     factory.afterPropertiesSet();  
  7.     UserService service = (UserService) factory.getObject();  
  8.     service.create("test""password");  
  9.     System.out.println(service.login("test""password"));  
  10.     try {  
  11.       service.login("test""bad-password");  
  12.     } catch (Exception e) {  
  13.       System.out.println(e.getMessage());  
  14.     }  
  15.   }  
  16. }  


如果客户端也在Spring容器中启动,完全可以在XML配置文件中定义UserService并直接使用
Xml代码 复制代码 收藏代码
  1. <bean id="userServiceRmi" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">  
  2.   <property name="serviceUrl" value="rmi://localhost:1099/UserService" />  
  3.   <property name="serviceInterface" value="example.rmi.UserService" />  
  4. </bean>  


RMI虽然是Java标准的远程调用模式,但是它使用特定的Java Remote Method Protocol二进制协议,很难穿透防火墙,如果要跨防火墙,应该使用HTTP协议为基础的远程调用。
Hessian; Burlap; Spring HTTP Invoker。使用私有协议的Http远程调用没有成为标准,实际应用较少,只能用于Java应用程序之间的远程调用。如果希望和异构平台实现远程调用,就必须使用标准的Web服务(Web Services) 
0 0
原创粉丝点击