• Spring远程调用技术<1>-RMI


    在java中,我们有多种可以使用的远程调用技术

    1.远程方法调用(remote method invocation, RMI) 

    适用场景:不考虑网络限制时(例如防火墙),访问/发布基于java的服务

     2.Caucho的Hession和Burlap

    适用场景:考虑网络限制时,通过http访问/发布基于java的服务。Hession是二进制协议,Burlap是基于XML的

     3.Spring基于HTTP的远程服务(HTTP invoke)

    适用场景:考虑网络限制,并希望使用基于xml或专有的序列化机制实现java序列化时,访问/发布基于Spring的服务

     4.使用JAX-RPC和JAX-WS的Web Server

    适用场景:访问/发布平台独立的、基于SOAP的Web服务

     5.还有EJB技术

    参考http://www.cnblogs.com/wwzyy/p/5655600.html

     这里远程方法的调用,方法的执行是在服务端执行的,客户端只是获取服务端处理完返回的结果。

    一、首先开始配置服务端,建立java普通项目就行

    先导入spring的jar包,这里使用的是spring4.1.1

    1.配置远程调用的接口(MyServer.java)

    package com.spring.rmiServer;
    
    public interface MyServer {
        
        public void getMsg();
        
        public String getMsgById(Integer id);
        
        public Integer add(Integer a, Integer b);
    
    }

    2.实现类(MyServerImpl.java)

    package com.spring.rmiServer;
    
    public class MyServerImpl implements MyServer {
    
        @Override
        public void getMsg() {
            System.out.println("call getMsg..");
    
        }
    
        @Override
        public String getMsgById(Integer id) {
            System.out.println("call getMsgById "+ id);
            return "id is "+id;
        }
    
        @Override
        public Integer add(Integer a, Integer b) {
            System.out.println("call add ");
            return a+b;
        }
    
    }

    3.配置RMI服务(RMIConfig.java),使用java配置的方式

    package com.spring.rmiServer;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.remoting.rmi.RmiServiceExporter;
    
    @Configuration
    public class RMIConfig {
        
        //@Bean()的name默认是方法名
        @Bean(name="rmiExporter")
        public RmiServiceExporter rmiExporter(MyServer myServer){
            RmiServiceExporter rmiExporter = new RmiServiceExporter();
            rmiExporter.setService(myServer);
            rmiExporter.setServiceName("My_server");
            rmiExporter.setServiceInterface(MyServer.class);
            //rmiExporter.setRegistryHost("localhost");
            rmiExporter.setRegistryPort(1199);//远程的端口
            return rmiExporter;
            
        }
        
        @Bean(name="myServer")
        public MyServer myServer(){
            return new MyServerImpl();
        }
    }

    4.启动服务

    public static void main(String[] args) {

         //当出现java.net.ConnectException: Connection refused: connect,可以这样解决,指定ip地址
         System.setProperty("java.rmi.server.hostname" , "192.168.23.128" );
    ApplicationContext ac = new AnnotationConfigApplicationContext(com.spring.rmiServer.RMIConfig.class);
          System.out.println("start rmi server.."); 

    }

    二、配置客户端

    1.配置要访问的远程接口,和服务端的那个接口一模一样,实现类不用写,因为服务端已经实现了,客户端调用就行

    (MyServer.java)

    package com.spring.rmiServer;
    
    public interface MyServer {
        
        public void getMsg();
        
        public String getMsgById(Integer id);
        
        public Integer add(Integer a, Integer b);
    
    }

    2.配置文件  (ClientContext.xml)

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
            <!-- 要调用的接口 -->
            <property name="serviceInterface" value="com.spring.rmiServer.MyServer"></property>
            <!-- url -->
            <property name="serviceUrl" value="rmi://192.168.23.128:1199/My_server"></property>
        </bean>
    </beans>

    3.启动客户端(Client.java)

        public static void main(String[] args) {
            
            ApplicationContext app = new ClassPathXmlApplicationContext("com/spring/rmiClient/ClientContext.xml");
        
            MyServer myServer = app.getBean(MyServer.class);
            
            System.out.println(myServer.getMsgById(03));
        }

     

    注意:有时候会由于主机ip的原因出现拒绝访问异常

    3种解决方法:

    1.  服务器端添加代码: System.setProperty("java.rmi.server.hostname" , "192.168.23.128" );上面代码使用的就是这种方法。

    2.  在 RMI 服务器上 root 身份登录,输入 Vi /etc/hosts ,在第一行添加 192.168.39.11     ieie

    3.  若是用 spring, 则在 RmiServiceExporter 中添加属性 <property name="registryHost"  value="192.168.23.128" />

    缺点:

    但是它存在某种限制,RMI很难穿越防火墙,这是RMI使用任意端口来交互(这是防火墙通常不允许的)。在企业内部网络幻境中,我们通常不需要担心。但如果在互联网运行,可能会有麻烦。

    还有就是RMI是基于java的,也就是说客户端和服务端必须都是由java开发,这样接口才能对得上。因为RMI使用了java的序列化机制,所以通过网络传输的对象类型必须要保证在调用两端的java运行中是完全相同的版本

  • 相关阅读:
    当今世界最为经典的十大算法投票进行时
    HDU_1203 I NEED A OFFER!
    POJ_2352 Stars(树状数组)
    HDU_1231 最大连续子序列
    POJ_3264 Balanced Lineup(线段树练手题)
    【转】休息几分种,学几个bash快捷键
    HDU_1013 Digital Roots
    HDU_1381 Crazy Search
    POJ_2528 Mayor's posters(线段树+离散化)
    zoj_1610 Count tht Color
  • 原文地址:https://www.cnblogs.com/wwzyy/p/6083090.html
Copyright © 2020-2023  润新知