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

简介: Hessian是一个轻量级的二进制远程调用框架,官方文档地址,它主要包括Hessian远程调用协议、Hessian序列化协议以及客户端服务端代理等几部分,关于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代码 复制代码  收藏代码
  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. }     
  16.    

 

2.远程服务接口类

Java代码 复制代码  收藏代码
  1. package hessian;        
  2.         
  3. public interface IHessian {         
  4.     public String say(TradeItemDto tradeItemDto);        
  5. }    

 

3.远程接口服务实现类

Java代码 复制代码  收藏代码
  1. package hessian;        
  2. import com.caucho.hessian.server.HessianServlet;        
  3. public class HessianImpl extends HessianServlet implements IHessian{        
  4.     public String say(TradeItemDto tradeItemDto) {         
  5.         return "Hello " + tradeItemDto.toString();        
  6.     }         
  7. }    

 

4.通过servlet暴露远程服务

Java代码 复制代码  收藏代码
  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代码 复制代码  收藏代码
  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代码 复制代码  收藏代码
  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调用原理决定客户端与服务端使用的接口类全限定名不必相同,只需方法名字参数要相同。

目录
相关文章
|
应用服务中间件 nginx
Nginx中如何配置中文域名?
Nginx中如何配置中文域名?
|
5月前
|
缓存 NoSQL Java
Redis:现代服务端开发的缓存基石与电商实践-优雅草卓伊凡
Redis:现代服务端开发的缓存基石与电商实践-优雅草卓伊凡
116 5
Redis:现代服务端开发的缓存基石与电商实践-优雅草卓伊凡
|
Java Spring
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
`@RequiredArgsConstructor(onConstructor = @__(@Autowired))` 是一个注解,通常用于在类中生成一个包含所有`final`和`@NonNull`注解的字段的构造函数,并且对这些字段进行自动注入(使用Spring框架的`@Autowired`注解)。让我们详细解释一下: 1. **`@RequiredArgsConstructor` 注解:** - **作用:** Lombok 提供的注解,用于自动生成类的构造函数。 - **生成的构造函数:** 生成一个包含所有`final`字段的构造函数,同时也包括被`@NonNull`注解
1302 1
|
12月前
|
数据挖掘 物联网 API
API接口在各个领域的发挥着什么样的作用呢
API接口在电商、金融、医疗、物联网、媒体和游戏等领域发挥重要作用。从商品管理、支付集成、用户管理,到金融风控、医疗数据共享、智能交通,再到内容整合、数据分析和游戏数据交互,API助力各行业实现高效协同与创新。
|
自然语言处理 JavaScript 前端开发
JDK序列化原理问题之FuryJDK序列化性能问题的如何解决
JDK序列化原理问题之FuryJDK序列化性能问题的如何解决
182 2
|
大数据 Linux Docker
mac docker 宿主机和容器间网络打通
mac docker 宿主机和容器间网络打通
213 0
|
开发工具
已设定选项 ‘readonly‘ (请加 ! 强制执行)
已设定选项 ‘readonly‘ (请加 ! 强制执行)
1240 0
|
Java 关系型数据库 MySQL
基于JAVA的高校宿舍管理系统的设计与实现(论文+源码)_kaic
基于JAVA的高校宿舍管理系统的设计与实现(论文+源码)_kaic
|
前端开发 JavaScript
js对map排序,后端返回有序的LinkedHashMap类型时前端获取后顺序依旧从小到大的解决方法
在后端进行时间倒序查询后,返回map类型的数据,在postman获取是这样:
809 0
使用flex布局实现,7种经典布局案例
使用flex布局实现,7种经典布局案例
857 0
使用flex布局实现,7种经典布局案例