Hessian轻量级二进制远程调用框架
2010-09-21 14:11
489 查看
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
2.远程服务接口类
3.远程接口服务实现类
4.通过servlet暴露远程服务
5.客户端远程服务调用类
客户端结果及服务端Debug输出
Hello 2999
下面是Debug输出,打印了hessian调用过程,我们说Hessian是二进制协议,它输出到流里面的都是二进制协议内容或者数据内容,区别于文本协议及文本数据内容。下面是hessian协议及hessian序列化的可视化,是为了帮助我们理解hessian调用过程。
备注:
1)3.13 以上版本支持debug,可以输出协议内容及序列化流
2)可以打开或者关闭远程调用方法是否可重载标志,方法参数个数必须固定,不支持变长参数
3) 注意客户端与服务端使用hessian.jar包版本
4)spring集成hessian
5)hessian调用原理决定客户端与服务端使用的接口类全限定名不必相同,只需方法名字参数要相同。
下面这个图是一次远程调用的过程
其中步骤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
package hessian; import java.math.BigDecimal; public class TradeItemDto implements java.io.Serializable { private static final long serialVersionUID = -1074152706947019647L; private BigDecimal amount; public BigDecimal getAmount(){ return amount; } public void setAmount(java.math.BigDecimal amount) { this.amount = amount; } public String toString() { return this.amount.toString(); } }
2.远程服务接口类
package hessian; public interface IHessian { public String say(TradeItemDto tradeItemDto); }
3.远程接口服务实现类
package hessian; import com.caucho.hessian.server.HessianServlet; public class HessianImpl extends HessianServlet implements IHessian{ public String say(TradeItemDto tradeItemDto) { return "Hello " + tradeItemDto.toString(); } }
4.通过servlet暴露远程服务
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <servlet> <servlet-name>ihessian</servlet-name> <servlet-class>hessian.HessianImpl</servlet-class> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>ihessian</servlet-name> <url-pattern>/test</url-pattern> </servlet-mapping> </web-app>
5.客户端远程服务调用类
package hessian; import java.net.MalformedURLException; import com.caucho.hessian.client.HessianProxyFactory; public class TestHessian { public static void main(String[] args) { String url = "http://localhost:8080/hessian/test"; HessianProxyFactory factory = new HessianProxyFactory(); IHessian h = null; try { h = (IHessian) factory.create(IHessian.class, url); } catch (MalformedURLException e) { System.out.println("occur exception: " + e); } TradeItemDto tradeItemDto = new TradeItemDto(); tradeItemDto.setAmount(new java.math.BigDecimal(2999)); System.out.println(h.say(tradeItemDto)); } }
客户端结果及服务端Debug输出
Hello 2999
下面是Debug输出,打印了hessian调用过程,我们说Hessian是二进制协议,它输出到流里面的都是二进制协议内容或者数据内容,区别于文本协议及文本数据内容。下面是hessian协议及hessian序列化的可视化,是为了帮助我们理解hessian调用过程。
17:48:38,169 ERROR [STDERR] 2010-9-25 17:48:38 com.caucho.hessian.server.HessianSkeleton$LogWriter write 良好: call 2.0 17:48:38,170 ERROR [STDERR] 2010-9-25 17:48:38 com.caucho.hessian.server.HessianSkeleton$LogWriter write 良好: method "say" 17:48:38,170 ERROR [STDERR] 2010-9-25 17:48:38 com.caucho.hessian.server.HessianSkeleton$LogWriter write 良好: map hessian.TradeItemDto (#0) 17:48:38,171 ERROR [STDERR] 2010-9-25 17:48:38 com.caucho.hessian.server.HessianSkeleton$LogWriter write 良好: "amount" => map java.math.BigDecimal (#1) 17:48:38,171 ERROR [STDERR] 2010-9-25 17:48:38 com.caucho.hessian.server.HessianSkeleton$LogWriter write 良好: "scale" => 0 17:48:38,171 ERROR [STDERR] 2010-9-25 17:48:38 com.caucho.hessian.server.HessianSkeleton$LogWriter write 良好: "intVal" => null 17:48:38,172 ERROR [STDERR] 2010-9-25 17:48:38 com.caucho.hessian.server.HessianSkeleton$LogWriter write 良好: Hessian 2.0 17:48:38,172 ERROR [STDERR] 2010-9-25 17:48:38 com.caucho.hessian.server.HessianSkeleton$LogWriter write 良好: Reply 17:48:38,173 ERROR [STDERR] 2010-9-25 17:48:38 com.caucho.hessian.server.HessianSkeleton$LogWriter write 良好: "Hello 2999"
备注:
1)3.13 以上版本支持debug,可以输出协议内容及序列化流
2)可以打开或者关闭远程调用方法是否可重载标志,方法参数个数必须固定,不支持变长参数
3) 注意客户端与服务端使用hessian.jar包版本
4)spring集成hessian
5)hessian调用原理决定客户端与服务端使用的接口类全限定名不必相同,只需方法名字参数要相同。
相关文章推荐
- Android Hessian轻量级二进制远程调用框架
- Hessian轻量级二进制远程调用框架
- Hessian轻量级二进制远程调用框架
- 轻量级远程调用框架-Hessian学习笔记-Demo实现
- 轻量级远程调用框架-Hessian学习笔记-Demo实现
- 轻量级远程调用框架-Hessian学习笔记-Demo实现
- 轻量级远程调用框架-Hessian学习笔记-Demo实现
- Hessian——轻量级的二进制协议远程调用实现方案
- 轻量级分布式 RPC 框架 远程调用
- Hessian--轻量级远程调用方案
- 基于 Hessian 轻量级远程调用的原理及示例
- Hessian——轻量级远程调用方案
- Hessian——轻量级远程调用方案
- Hessian远程调用框架进阶教程(一) Hessian介绍JAVA使用Hessian进行编程实例
- [转]Hessian——轻量级远程调用方案
- 比WebService更简单的远程调用方案框架:Hessian
- Spring + Hessian 实现轻量级分布式远程调用【包含rmi方式重构】
- Hessian 远程调用框架(Java跨工程调用接口)
- Hessian 远程调用框架
- 关于远程调用(XFire/HttpInvoker/Hessian etc.)及远程服务管理的一些随想