zoukankan      html  css  js  c++  java
  • java rpc 综述(上)

    记得来newland面试的时候,有一个笔试题是关于rmi,rpc cobar web service的选择题。当时对这些不是很懂,除了一个Web Service.

    那时候天真的认为要远程调用服务除了Web Service还是Web Service。

    最近晚上正好有时候,就介绍下java中几种调用rpc的方式吧。

    一、RMI

    RMI(remote method Invocation)远程方法调用,从JDK1.1开始就出现,极大的增强了java的分布式处理能力。

    相对于其他的rpc,RMI

    优势在于无需引入其他外部的jar包,对于处理一些小的应用,会非常的方便和轻巧。

    劣势是只能是java-to-java模式,无法使用其他语言来调用。

    为了弥补RMI的劣势,后面出现了RMI-IIOP,极大的兼容了COBRA。当然,这不是本篇文章的主题。

    那么如何调用RMI呢?这里给出一个简单的例子。

    1.创建接口

    说明的是这个接口必须继承Remote类,同时远程调用的所有方法都需要抛出RemoteException异常

    1 public interface IHello extends Remote{
    2     /**
    3      * 远程调用的接口 必须抛出 RemoteException
    4      * */
    5     public String say(String msg)throws RemoteException;
    6 
    7 }

    2.创建接口实现类

     1 public class IHelloImpl extends UnicastRemoteObject implements IHello {
     2 
     3     /**
     4      * 因为UnicastRemoteObject的构造方法抛出了RemoteException异常,因此这里默认的构造方法必须写,必须声明抛出RemoteException异常
     5      * 
     6      * @throws RemoteException
     7      */
     8     public IHelloImpl() throws RemoteException {
     9         super();
    10         // TODO Auto-generated constructor stub
    11     }
    12 
    13     public String say(String msg) {
    14         // TODO Auto-generated method stub
    15         return "远程接口调用:" + msg;
    16     }
    17 
    18 }

    3.注册开启本地RMI服务

     1 public class HelloServer {
     2 
     3     public HelloServer() {
     4     }
     5 
     6     public static void main(String[] args) {
     7         new HelloServer().start();
     8     }
     9 
    10     private void start() {
    11 
    12         try {
    13             IHello hello = new IHelloImpl();
    14             // 创建注册表对象
    15             LocateRegistry.createRegistry(10000);
    16             // banding远程对象到RIMI注册表上 rmi协议可以缺省
    17             Naming.bind("rmi://localhost:10000/RHello", hello);
    18             System.out.println("启动远程RMI注册服务");
    19 
    20         } catch (RemoteException e) {
    21             // TODO Auto-generated catch block
    22             e.printStackTrace();
    23         } catch (MalformedURLException e) {
    24             // TODO Auto-generated catch block
    25             e.printStackTrace();
    26         } catch (AlreadyBoundException e) {
    27             // TODO Auto-generated catch block
    28             e.printStackTrace();
    29         }
    30 
    31     }
    32 
    33 }

    4.测试

    1 //远程服务如果未开 则抛出Connection refused to host
    2             IHello hello=(IHello) Naming.lookup("//localhost:10000/RHello");
    3             System.out.println(hello.say("你好"));

    二、XML-RPC

    官网地址:http://ws.apache.org/xmlrpc/index.html

    XML-RPC(XML-based Remote Procedure Call,基于 XML 的远程过程调用)是一种已http协议,XML格式为载体的RPC。

    XML-RPC 具有简单、高效且易于实现等优点,因此她也一直是中小型引用实现分布式的最佳方案之一。

    官网对于XML-RPC的有点给出了以下解释(自己翻译)

    1.支持所有java的基础类型

    2.日历对象也是支持的,特别timezone和milliseconds也是可以进行发送请求的。

    3.DOM nodes, or JAXB objects也是允许被传输的。最重要的是实现了java.io.Serializable interface

    接口的对象都是允许的,话外之音,开发者自定义的实体对象都是允许的。nice.(*^__^*) 

    4.服务端和客户端都运行在流模式中,远比默认的模式(基于内部的大数据字节数组)来的好。

    更多关于XML-RPC类型 参考这里:http://ws.apache.org/xmlrpc/types.html

    理论说完,我们就来编写一个XML-RPC的例子。这里针对的是XML-RPC2.0的库进行开发的3.x就有区别了

    首先创建一个java web project。引入xercesImpl-2.9.1.jar,xmlrpc-2.0.jar,xmlrpc-client-3.1.3.jar包

    另外还需要引入commons-codec-1.3.jar,否则会提示org/apache/commons/codec/DecoderException

    1.创建服务

    //xml rpc 服务类 
    public class MyXmlRpcServer {
    
        public byte[] test(int flag) {
    
            if (flag==1)
                return "admin".getBytes();
            else
                return "guest".getBytes();
        }
    
    }

    2.创建一个servlet。

    public class XmlRpcServlet extends HttpServlet {
    
        private XmlRpcServer rpcServer=new XmlRpcServer();
    
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            doPost(request, response);
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
             byte[] result = rpcServer.execute(request.getInputStream());
               response.setContentType("text/xml");
               response.setContentLength(result.length);
               OutputStream out = response.getOutputStream();
               out.write(result);
               out.flush();
               out.close();
        }
        
    
        public void init() throws ServletException {
            //定义一个服务名为myServer的xml rpc服务
            rpcServer.addHandler("myServer", new MyXmlRpcServer());
            rpcServer.setMaxThreads(20);
        }
    
    }

    需要说明的是doPost方法中的返回值,是根据MyXmlRpcServer 类的方法进行强转化的,并且ContentType 必须是

    text/xml,而不是原先servlet自带的text/html。
    <servlet>
        <servlet-name>XmlRpcServlet</servlet-name>
        <servlet-class>com.lwx.xmlrpc.servlet.XmlRpcServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>XmlRpcServlet</servlet-name>
        <url-pattern>/XmlRpcServer</url-pattern>
      </servlet-mapping>

    3.客户端

    public class ClientTest {
        public static void main(String[] args) throws ClassNotFoundException,
                XmlRpcException, IOException {
            // 1.加载驱动
            XmlRpc.setDriver("org.apache.xerces.parsers.SAXParser");
            XmlRpcClient client = new XmlRpcClient(
                    "http://localhost:10000/XmlRpcTest/XmlRpcServer");
            Vector params = new Vector();
            params.addElement(1);
            byte role[] = (byte[]) client.execute("myServer.test", params);
            System.out.println(new String(role));
            
        }

    如果对XML-RPC3.0感兴趣的可以参考

    http://chrui.iteye.com/blog/800447

    http://blog.sina.com.cn/s/blog_76fbd24d01018z6g.html

    自然,需要研究的话 本篇文章可以看看 http://www.ibm.com/developerworks/cn/webservices/1211_zhusy_rpc/index.html#ibm-pcon

    关于XML-RPC的完整例子 可以从这里下载http://download.csdn.net/detail/draem0507/5346924

    小结:上面我们简单介绍了RMI和XML-RPC2.0,感兴趣的朋友可以研究RMI-IIOP ,COBRA。当然XML-RPC3.0

    也看去看下,顺便补充一句.XML-RPC客户端发送的请求有两种方式

    第一种就是例子中的,使用的是Java.net.URLConnection。

    第二种是org.apache.xmlrpc.XmlRpcClientLite:自身提供轻量级的http client实现

    加入我们需要使用http协议(代理,重定向)则必须使用第一种方式,否则的话第二种方式值得考虑。

    最重要的是根据平台来决定,有的平台第一种更快,有的则是第二种。

    打个广告,java rpc 综述(下) 将重点介绍下基于SAOP的Web Service。有机会会结合android的天气预报的例子来做说明。

    另外:求一份福州android的offer。嘎嘎。

     

     

  • 相关阅读:
    java学习6-java基础类库
    java学习5-面向对象(下)
    java学习4-面向对象(上)
    java学习3-流程控制与数组
    java学习2-数据类型和运算符
    pycharm(社区版2019.1版本)打开README.md文件卡死解决办法
    python深拷贝与浅拷贝的区别
    python中list切片详解
    python使用input().split()接收多个用户输入
    python学习-语言概述(一)
  • 原文地址:https://www.cnblogs.com/draem0507/p/3067888.html
Copyright © 2011-2022 走看看