• Hessian轻量级二进制远程调用框架


     

    Hessian轻量级二进制远程调用框架

    Hessian是一个轻量级的二进制远程调用框架,官方文档地址,它主要包括Hessian远程调用协议、Hessian序列化协议以及客户端服务端代理等几部分,关于Hessian协议可以看下另外一篇文章Hessian远程调用及序列化协议。Hessian远程调用框架构建在Http协议之上,下面是示意图。

    下面这个图是一次远程调用的过程

    其中步骤3、4、5、6是核心过程,还要细化下,

    步骤3:将远程方法调用转换为hessian调用,具体为,客户端首先要先和服务器端建立Socket连接,然后发送Http请求,hessian远程调用及经过Hessian序列化的参数等二进制数据作为http请求的数据部分被提交到服务端,并且目前只支持Post提交方法。

    步骤4:将hessian调用转换为本地方法调用,步骤3里请求的url是暴露服务时映射好的,也即指定的服务端代理对象会解析客户端服务代理对象进行的hessian远程调用,然后反序列化参数,找到被代理的服务类(暴露服务时指定的服务类),通过反射调用服务类中的相应服务方法。

    步骤5:返回远程调用返回值给服务调用者,步骤4里调用服务类的方法会返回具体值,经过Hessian序列化后作为hessian调用的返回值,被放在http响应的body部分被返回给客户端。

    步骤6:客户端代理对象解析body部分hessian调用返回reply,解析出远程调用返回值再反序列化,最终得到结果。

    再此举例说明:

    先看一下demo中涉及到的对象,其中灰色部分Proxy$N、HessianSkeleton分别对应第一张图里面的客户端远程代理对象和服务端代理对象。深绿色部分HessianProxy是创建动态代理时所需的InvocationHandler,HessianProxy和HessianSkeleton是hessian框架的核心类。一般都是在客户端通过HessianProxyFactory创建一个动态代理,将远程方法调用转为http请求携带hessian调用数据,并接受相应的返回值。HessianSkeleteton代理具体的服务类比如HessianImpl,最终一个远程方法调用都会转换为对HessianImpl中的本地方法调用。

    1.实体类TradeItemDto

    [java] view plaincopy
     
    1. package hessian;  
    2. import java.math.BigDecimal;  
    3. public class TradeItemDto implements java.io.Serializable {  
    4.     private static final long serialVersionUID = -1074152706947019647L;  
    5.     private BigDecimal amount;  
    6.     public BigDecimal getAmount(){  
    7.         return amount;  
    8.     }     
    9.     public void setAmount(java.math.BigDecimal amount) {  
    10.         this.amount = amount;  
    11.     }     
    12.     public String toString() {  
    13.         return this.amount.toString();    
    14.     }     
    15. }  

    2.远程服务接口类

    [java] view plaincopy
     
    1. package hessian;    
    2.     
    3. public interface IHessian {     
    4.     public String say(TradeItemDto tradeItemDto);    
    5. }  

    3.远程接口服务实现类

    [java] view plaincopy
     
    1. package hessian;    
    2.     
    3. import com.caucho.hessian.server.HessianServlet;    
    4.     
    5. public class HessianImpl extends HessianServlet implements IHessian{    
    6.     
    7.     public String say(TradeItemDto tradeItemDto) {     
    8.         return "Hello " + tradeItemDto.toString();    
    9.     }     
    10. }  

    4.通过servlet暴露远程服务

    [xhtml] view plaincopy
     
    1. <?xml version="1.0" encoding="UTF-8"?>    
    2. <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
    3.     version="2.4"    
    4.     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">  
    5.     
    6.     <servlet>    
    7.         <servlet-name>ihessian</servlet-name>    
    8.         <servlet-class>hessian.HessianImpl</servlet-class>   
    9.         <init-param>  
    10.             <param-name>debug</param-name>  
    11.             <param-value>true</param-value>  
    12.         </init-param>  
    13.     </servlet>    
    14.     <servlet-mapping>    
    15.         <servlet-name>ihessian</servlet-name>    
    16.         <url-pattern>/test</url-pattern>          
    17.     </servlet-mapping>    
    18. </web-app>  

    5.客户端远程服务调用类

    [java] view plaincopy
     
    1. package hessian;   
    2. import java.net.MalformedURLException;   
    3. import com.caucho.hessian.client.HessianProxyFactory;   
    4. public class TestHessian {   
    5.     public static void main(String[] args) {   
    6.         String url = "http://localhost:8080/hessian/test";   
    7.         HessianProxyFactory factory = new HessianProxyFactory();   
    8.         IHessian h = null;   
    9.         try {   
    10.             h = (IHessian) factory.create(IHessian.class, url);   
    11.         } catch (MalformedURLException e) {   
    12.             System.out.println("occur exception: " + e);   
    13.         }   
    14.         TradeItemDto tradeItemDto = new TradeItemDto();   
    15.         tradeItemDto.setAmount(new java.math.BigDecimal(2999));   
    16.         System.out.println(h.say(tradeItemDto));   
    17.     }  
    18. }  
     

    客户端结果及服务端Debug输出

    Hello 2999

    下面是Debug输出,打印了hessian调用过程,我们说Hessian是二进制协议,它输出到流里面的都是二进制协议内容或者数据内容,区别于文本协议及文本数据内容。下面是hessian协议及hessian序列化的可视化,是为了帮助我们理解hessian调用过程。

    [java] view plaincopy
     
    1. 17:48:38,169 ERROR [STDERR] 2010-9-25 17:48:38 com.caucho.hessian.server.HessianSkeleton$LogWriter write  
    2. 良好: call 2.0  
    3. 17:48:38,170 ERROR [STDERR] 2010-9-25 17:48:38 com.caucho.hessian.server.HessianSkeleton$LogWriter write  
    4. 良好:   method "say"  
    5. 17:48:38,170 ERROR [STDERR] 2010-9-25 17:48:38 com.caucho.hessian.server.HessianSkeleton$LogWriter write  
    6. 良好:   map hessian.TradeItemDto (#0)  
    7. 17:48:38,171 ERROR [STDERR] 2010-9-25 17:48:38 com.caucho.hessian.server.HessianSkeleton$LogWriter write  
    8. 良好:     "amount" => map java.math.BigDecimal (#1)  
    9. 17:48:38,171 ERROR [STDERR] 2010-9-25 17:48:38 com.caucho.hessian.server.HessianSkeleton$LogWriter write  
    10. 良好:                   "scale" => 0  
    11. 17:48:38,171 ERROR [STDERR] 2010-9-25 17:48:38 com.caucho.hessian.server.HessianSkeleton$LogWriter write  
    12. 良好:                   "intVal" => null  
    13. 17:48:38,172 ERROR [STDERR] 2010-9-25 17:48:38 com.caucho.hessian.server.HessianSkeleton$LogWriter write  
    14. 良好: Hessian 2.0  
    15. 17:48:38,172 ERROR [STDERR] 2010-9-25 17:48:38 com.caucho.hessian.server.HessianSkeleton$LogWriter write  
    16. 良好: Reply  
    17. 17:48:38,173 ERROR [STDERR] 2010-9-25 17:48:38 com.caucho.hessian.server.HessianSkeleton$LogWriter write  
    18. 良好:   "Hello 2999"  

    备注:

    1)3.13 以上版本支持debug,可以输出协议内容及序列化流

    2)可以打开或者关闭远程调用方法是否可重载标志,方法参数个数必须固定,不支持变长参数

    3) 注意客户端与服务端使用hessian.jar包版本

    4)spring集成hessian

    5)hessian调用原理决定客户端与服务端使用的接口类全限定名不必相同,只需方法名字参数要相同。

  • 相关阅读:
    Java Volatile keyword
    解决 The &#39;InnoDB&#39; feature is disabled; you need MySQL built with &#39;InnoDB&#39; to have it working
    【玩转cocos2d-x之三十九】Cocos2d-x 3.0截屏功能集成
    【DP】UVA 624 CD 记录路径
    ns3加入模块之vanet-highway
    awk向脚本传递參数(二)
    【传递正能量】献给默默追梦的人
    算法(第四版)学习笔记之java实现可以动态调整数组大小的栈
    Webstorm/IntelliJ Idea 过期破解方法
    CenterOS下安装NodeJS
  • 原文地址:https://www.cnblogs.com/caogang/p/4598244.html
Copyright © 2020-2023  润新知