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
- 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调用原理决定客户端与服务端使用的接口类全限定名不必相同,只需方法名字参数要相同。
Hessian轻量级二进制远程调用框架的更多相关文章
- ZooKeeper伪分布集群安装及使用 RMI+ZooKeeper实现远程调用框架
使用 RMI + ZooKeeper 实现远程调用框架,包括ZooKeeper伪集群安装和代码实现两部分. 一.ZooKeeper伪集群安装: 1>获取ZooKeeper安装包 下载地址:ht ...
- ZeroC ICE的远程调用框架 Slice如何帮助我们进行Ice异步编程(AMI,AMD)
Slice最大的用处就是为我们使用Ice进行编程,代劳绝大部分的重复性代码,并提供一些帮助性的框架代码,如用于AMI和AMD方式进行异步编程的回调框架. 当Slice不为我们生成代码时,我们仍然可以按 ...
- ZeroC ICE的远程调用框架 AMD
继上一篇<ZeroC ICE的远程调用框架>,本篇再来说其中的AMD.(本篇需要重写) 当在ice文件中声明某个接口方法Method为["amd"]后,接口方法在stu ...
- ZeroC ICE的远程调用框架
想搞清楚slice为我们生成了什么样的框架代码,就先搞明白Ice的远程调用框架暗中为我们做了些什么? Ice将Ice Object的方法调用分为三个阶段(或步骤),分别是begin,process和e ...
- Hessian怎样实现远程调用
1.Spring中除了提供HTTP调用器方式的远程调用,还对第三方的远程调用实现提供了支持,其中提供了对Hessian的支持. Hessian是由Caocho公司发布的一个轻量级的二进制协议远程调用实 ...
- alibaba远程调用框架dubbo原理
alibaba有好几个分布式框架,主要有:进行远程调用(类似于RMI的这种远程调用)的(dubbo.hsf),jms消息服务(napoli.notify),KV数据库(tair)等.这个框架/工具/产 ...
- 使用 RMI + ZooKeeper 实现远程调用框架
目录[-] 1 发布 RMI 服务1.1 定义一个 RMI 接口1.2 编写 RMI 接口的实现类1.3 通过 JNDI 发布 RMI 服务2 调用 RMI 服务3 RMI 服务的局限性4 使用 Zo ...
- [转载] 基于Dubbo的Hessian协议实现远程调用
转载自http://shiyanjun.cn/archives/349.html Dubbo基于Hessian实现了自己Hessian协议,可以直接通过配置的Dubbo内置的其他协议,在服务消费方进行 ...
- 基于Dubbo的Hessian协议实现远程调用
Dubbo基于Hessian实现了自己Hessian协议,可以直接通过配置的Dubbo内置的其他协议,在服务消费方进行远程调用,也就是说,服务调用方需要使用Java语言来基于Dubbo调用提供方服务, ...
随机推荐
- C++ string(STL)
发现字符串问题中 string 好厉害- string类的构造函数: string(const char *s); //用c字符串s初始化 string(int n,char c); //用n个字符c ...
- navicat修改mysql用户密码,前提是能登陆
幸亏之前已经连上了数据库后边才忘记密码
- 学习Python笔记---列表简介
列表: 列表由一系列按特定顺序排列的元素组成.你可以创建包涵字母表中所有字母.数字0-9或所有家庭成员姓名的列表:也可以将任何东西加入列表中,其中的元素之间可以没有任何关系. 列表 在Python中, ...
- python 数据组合
- 计算机网络5.2-5 ipv4&路由协议&ipv6
子网变址技术 子网掩码 默认子网掩码 子网地址 广播地址 一些计算 CIDR 分配举例 地址不必连续分配 sadsdas 网络设备---路由器 输出结构 直接交付与简介交付 IP分组的转发 分属于不同 ...
- BZOJ 4420二重镇题解
链接 思路借鉴了这个博客: 我们可以想到状压dp 用一个十进制数来表示状态,即第i位表示位置i处的物品等级 用f[i][j][k]表示第i天,仓库的物品等级为j,状态为k时的最大收益 但是状态数貌似很 ...
- The 16th UESTC Programming Contest Final 游记
心情不好来写博客. 为了满足ykk想要气球的愿望,NicoDafaGood.Achen和我成功去神大耍了一圈. 因为队名一开始是LargeDumpling应援会,然后队名被和谐,变成了学校的名字,顿时 ...
- 【JZOJ4812】【NOIP2016提高A组五校联考2】string
题目描述 给出一个长度为n, 由小写英文字母组成的字符串S, 求在所有由小写英文字母组成且长度为n 且恰好有k 位与S 不同的字符串中,给定字符串T 按照字典序排在第几位. 由于答案可能很大,模10^ ...
- django查看数据库
#views import pymysql def get_date(request): conn = pymysql.connect( host='localhost', port=3306, us ...
- Directx11教程(57) 环境映射
原文:Directx11教程(57) 环境映射 建好skydome后,如果我们想让其中的某个物体,比如那个球体来映射出周围环境的蓝天白云(不包括自己附近的物体),该怎么做呢?此时可以把这个 ...