Hessian 协议解析

Hessian 协议解析Hessian 是由 caucho 提供的一个基于 binary RPC 实现的远程通讯 library 它是高性能二进制协议 支持很多种语言 众所周知大名鼎鼎的开源 rpc 的框架中都有使用 以下内容的理解均来自官网 1 0 2 协议 为降低理解上的偏差会大量使用源引用 目录 1 设计目标 2 数据类型 2 1null2 2boolean2 3int2 4long

Hessian 是由 caucho 提供的一个基于 binary-RPC 实现的远程通讯 library 。它是高性能二进制协议,支持很多种语言,众所周知大名鼎鼎的开源rpc的框架中都有使用。

以下内容的理解均来自官网1.0.2协议,为降低理解上的偏差会大量使用源引用。

目录

1. 设计目标

2. 数据类型

2.1 null

2.2 boolean

2.3 int

2.4 long

2.5 double

2.6 date

2.7 string

2.8 xml

2.9 binary

2.10 list

2.11 map

2.12 ref

2.13 remote

3. call

3.1 非规约对象命名

3.2 Methods and Overloading

3.3 Arguments

3.4 Headers

3.5 Versioning

4. Reply

4.1 Value

4.2 Faults

5. 非规约元数据

6. Micro Hessian

7. 格式定义

8. 变更

changes in 1.0.2

changes in 1.0

changes in V3

changes in V2

9. 实例


1. 设计目标

The Hessian web services protocol was created as a lightweight binary alternative to the XML-based web services protocols.

Hessian Web服务协议是作为基于XML的Web服务协议的轻量级二进制备选方案创建的。

Unlike older binary protocols, Hessian is both self-describing and portable across languages. The wire protocol for web services should be invisible to application writers. Wire protocols should not require external schema or IDL.

与旧的二进制协议不同,Hessian是跨语言的自描述和可移植的。Web服务的Wire协议应该是应用程序作者不可见的。在线协议不需要外部模式或IDL。

Given the EJB environment, the Hessian protocol has the following requirements:

考虑到EJB环境,Hessian协议具有以下要求:

  • It must support XML as a first class object.   
  • It must not require external IDL or schema definitions; it should be invisible to application writers.
  • It must have sufficient power to serialize Java.
  • It must have sufficient power to support EJB.
  • It must allow non-Java clients to use web services.
  • It must allow web services to deployed as a Servlet.
  • It must be simple so it can be effectively tested.
  • It must be as fast as possible.
  • It should support transaction contexts.

2. 数据类型

Hessian的对象序列化有9种基本类型:boolean、32-bit int、64-bit long、64-bit double、64-bit date、UTF8-encoded string、UTF8-encoded xml、raw binary data、remote objects

然后,它还有2个组合结构:

  1. list for lists and arrays
  2. map for objects and hash tables

最后,它有2个特殊结构:

  1. null for null values
  2. ref for shared and circular object references.

2.1 null

NULL表示空指针。字节“N”表示空指针。允许null代替任何string, xml, binary, list, map, or remote。

2.2 boolean

字节’F’表示false,字节’T’表示true。

2.3 int

一个32位有符号整数。一个整数由字节“I”表示,后面是整数字节的4字节。

2.4 long

一个64位有符号整数。一个长是用字节“L”表示的,后面是8字节的整数。

2.5 double

一个64位双精度浮点类型

2.6 date

Date是由64-bits位长包含毫秒的数据类型

2.7 string

2.8 xml

request:

hello

response:X x00 x10

hello


2.9 binary

二进制数据是用块编码的。B表示最终块,b表示任何初始块。每个块具有16位长度值。

2.10 list

一个有序的列表,就像一个数组。所有的列表都有一个类型字符串,一个长度,一个对象列表和一个尾随的“z”。类型字符串可以是服务所理解的任意UTF-8字符串(通常是Java类名,但这不是必需的)。长度可以是-1,以指示该列表是可变长度的。

语法:list ::= V type? length? object* z

2.11 map

表示序列化object和map。type元素描述map的类型。object由字段名到它们的值的map表示,type是对象本身的类。类型可以是空的,即零长度。如果未指定类型,则分析器负责选择类型。对于对象,将忽略未识别的键。每个map被添加到引用列表中。分析器期望map的任何时候,它也必须能够支持NULL或REF。

语法: M t b16 b8 type-string (object, object)* z

request: //Java Object
    public class Car implements Serializable {

      String model = “Beetle”;
      String color = “aquamarine”;
      int mileage = 65536;
    }
response:
    M t x00 x13 com.caucho.test.Car
      S x00 x05 model
      S x00 x06 Beetle
      
      S x00 x05 color
      S x00 x0a aquamarine
























request2: //A sparse array
    map = new HashMap();
    map.put(new Integer(1), “fee”);
    map.put(new Integer(16), “fie”);
    map.put(new Integer(256), “foe”);
response2:
    M I x00 x00 x00 x01
      S x00 x03 fee














      z

2.12 ref

An integer referring to a previous list or map instance. As each list or map is read from the input stream, it is assigned the integer position in the stream, i.e. the first list or map is ‘0’, the next is ‘1’, etc. A later ref can then use the previous object. Writers are not required to generate refs, but parsers must be able to recognize them.ref can refer to incompletely-read items. For example, a circular linked-list will refer to the first link before the entire list has been read.A possible implementation would add each map and list to an array as it’s read. The ref will return the corresponding object from the array. To support circular structures, the implementation would store the map or list immediately, before filling in the object’s contents.Each or

is stored into an array as it is parsed.

selects one of the stored objects. The first object is numbered ‘0’.

语法:R b32 b24 b16 b8

2.13 remote

对远程对象的引用。remote 有一个type 和一个UTF-8字符串,表示对象的URL。

语法:r t b16 b8 type-name S b16 b8 url

3. call

一个Hessian调用调用一个带有参数列表的对象的方法。对象是由容器指定的,例如对于HTTP请求,它是HTTP URL。参数由Hessian序列化指定。

语法:c x01 x00 header* m b16 b8 method-string (object)* z

request: c x01 x00   //obj.add2(2,3)
          m x00 x04 add2
          I x00 x00 x00 x02
          I x00 x00 x00 x03
          z
response:r x01 x00
          I x00 x00 x00 x05
          z














3.1 非规约对象命名

URL足够灵活,可以对对象实例以及简单的静态服务位置进行编码。URL唯一地标识Hessian对象。因此,Hessian可以支持由URL指定的面向对象的服务,例如命名服务、实体bean或会话bean,而不需要额外的方法参数或头。对象命名可以使用查询字符串约定”?id=XXX”在给定的服务中命名对象“xxx”。本公约是推荐的,但不是必需的。

http://hostname/hessian/ejb-name?id=object-id

http://hostname/hessian 标识EJB容器。在树脂EJB中,这将引用EJB servlet。/hessian”是servlet前缀(url-pattern)。HTTP只是用作示例;Hessian不需要使用HTTP。

/ejb-name, 请求的路径信息,标识EJB名称,特别是Home接口。EJB容器可以包含多个实体和会话bean,每个bean都有自己的EJB Home。EJB名称对应于部署描述符中的EJB名称。

object-id ,标识特定对象。对于实体bean,对象ID对主键进行编码。对于会话bean,对象ID编码唯一的会话标识符。家庭接口没有“;EJBID=…”部分。

3.2 Methods and Overloading

方法名称必须是唯一的。支持两种类型的重载:参数数重载和参数类型重载。通过对方法名称中的参数类型进行编码,允许重载。必须使用实际参数的类型来选择方法。保留了从 _hessian_ 开始的方法名称。服务器应该接受带有已损坏的方法名或未加密的方法名的调用。客户端应该发送被损坏的方法名。

3.3 Arguments

参数紧随位置顺序的方法。参数值使用Hessian的序列化。所有参数都共享引用,即引用列表从第一个参数开始,并针对所有其他参数继续。这允许两个参数共享值。

remote.eq(bean, bean)

bean = new qa.Bean("foo", 13); System.out.println(remote.eq(bean, bean));
c x01 x00 m x00 x02 eq M t x00 x07 qa.Bean S x00 x03 foo I x00 x00 x00 x0d z R x00 x00 x00 x00 z

3.4 Headers

Headers 是(string、object)对参数的预处理。标头的值可以是任何序列化对象。例如,请求可能包括头中的事务上下文。

Call with Distributed Transaction Context

c x01 x00 H x00 x0b transaction r t x00 x28 com.caucho.hessian.xa.TransactionManager S x00 x23 http://hostname/xa?ejbid=01b8e19a77 m x00 x05 debug I x00 x03 x01 xcb z

3.5 Versioning

调用和响应标记包括一个主字节和一个小字节。当前版本为1。

4. Reply

4.1 Value

成功的答复返回单个值和可能的一些头信息。

4.2 Faults

失败的调用返回fault。每个故障都有许多信息字段,如

条目。定义的字段是code, message, and detail。code是下面定义的字符串的一个简短列表之一。message是用户可读的消息。detail是表示异常的对象。在java中,detail将是序列化的异常。

ProtocolException The Hessian request has some sort of syntactic error.
NoSuchObjectException The requested object does not exist.
NoSuchMethodException The requested method does not exist.
RequireHeaderException A required header was not understood by the server.
ServiceException The called method threw an exception.

5. 非规约元数据

数据是通过特殊方法调用来处理的,方法是从_hessian_开始的。

_hessian_getAttribute(String key) returns a string.

Hessian 协议解析

对于没有对象实例(即非工厂服务)的服务,所有三个属性将返回相同的类名。

过时的元数据属性:

Hessian 协议解析

6. Micro Hessian

“Micro Hessian”实现可以省略对“双”类型的支持。

7. 格式定义

top ::= call ::= replycall ::= c x01 x00 header* methodobject* z reply ::= r x01 x00 header* object z ::= r x01 x00 header* fault z object ::= null ::= boolean ::= int ::= long ::= double ::= date ::= string ::= xml ::= binary ::= remote ::= ref ::= list ::= mapheader ::= H b16 b8 header-string objectmethod ::= m b16 b8 method-string fault ::= f (objectobject)* z list ::= V type? length? object* z map ::= M type? (objectobject)* z remote ::= r type? stringtype ::= t b16 b8 type-string length ::= l b32 b24 b16 b8 null ::= N boolean ::= T ::= F int ::= I b32 b24 b16 b8 long ::= L b64 b56 b48 b40 b32 b24 b16 b8 double ::= D b64 b56 b48 b40 b32 b24 b16 b8 date ::= d b64 b56 b48 b40 b32 b24 b16 b8 string ::= (s b16 b8 string-data)* S b16 b8 string-data xml ::= (x b16 b8 xml-data)* X b16 b8 xml-data binary ::= (b b16 b8 binary-data)* B b16 b8 binary-data ref ::= R b32 b24 b16 b8

8. 变更

changes in 1.0.2

  • Clarified that length of XML and strings is in characters (Petr Gladkikh)

changes in 1.0

  • Removed unidirectional messages.

changes in V3

  • Added unidirectional messages
  • Removed ‘v’ from reply
  • changed length code to ‘l’
  • made type and length optional

changes in V2

  • EJB naming: clarified examples especially for session beans (John Mitchell)
  • Formal definitions: clarified grammar and added missing object (John Mitchell)
  • Formal definitions: initial binary should use ‘b’ (John Mitchell

9. 实例

public static 
   
     byte[] serialize(T input) { if (input == null) throw new NullPointerException("input is requird."); byte[] result = null; ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); HessianSerializerOutput hessianSerializerOutput = null; try { hessianSerializerOutput = new HessianSerializerOutput(outputStream); //write本身是线程安全的 hessianSerializerOutput.writeObject(input); hessianSerializerOutput.close(); result = outputStream.toByteArray(); } catch (Exception ex) { throw new RuntimeException(ex); } finally { IOUtils.closeQuietly(outputStream); } return result; } public static 
    
      T deserialize(Class 
     
       retCls, byte[] input) { if (input == null) throw new NullPointerException(); T result = null; ByteArrayInputStream byteArrayInputStream = null; try { byteArrayInputStream = new ByteArrayInputStream(input); HessianSerializerInput hessianInput = new HessianSerializerInput(byteArrayInputStream); result = (T) hessianInput.readObject(); } catch (Exception e) { throw new RuntimeException(e); } finally { IOUtils.closeQuietly(byteArrayInputStream); } return result; } 
      
     
   

dubbo 协议基于 hessian 作为序列化协议。使用的场景是:传输数据量小(每次请求在 100kb 以内),但是并发量很高。Hessian 协议解析

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/212687.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午7:30
下一篇 2026年3月18日 下午7:30


相关推荐

  • java递归算法详解_Java递归算法详解(动力节点整理)

    java递归算法详解_Java递归算法详解(动力节点整理)递归算法是一种直接或者间接调用自身函数或者方法的算法 Java 递归算法是基于 Java 语言实现的递归算法 递归算法的实质是把问题分解成规模缩小的同类问题的子问题 然后递归调用方法来表示问题的解 递归算法对解决一大类问题很有效 它可以使算法简洁和易于理解 递归算法解决问题的特点 1 递归就是方法里调用自身 2 在使用递增归策略时 必须有一个明确的递归结束条件 称为递归出口 3 递归算法解题通常显得很

    2025年6月11日
    5
  • acwing-个简单的整数问题2(线段树+懒惰标记)「建议收藏」

    acwing-个简单的整数问题2(线段树+懒惰标记)「建议收藏」原题链接给定一个长度为 N 的数列 A,以及 M 条指令,每条指令可能是以下两种之一:C l r d,表示把 A[l],A[l+1],…,A[r] 都加上 d。Q l r,表示询问数列中第 l∼r 个数的和。对于每个询问,输出一个整数表示答案。输入格式第一行两个整数 N,M。第二行 N 个整数 A[i]。接下来 M 行表示 M 条指令,每条指令的格式如题目描述所示。输出格式对于每个询问,输出一个整数表示答案。每个答案占一行。数据范围1≤N,M≤105,|d|≤10000,|A[

    2022年8月8日
    9
  • css修改多选框的样式

    css修改多选框的样式每日的艰辛历程 最开始做好的是左边这个样子 设计师说害太丑了 做成右边这种吧 然后就改呗 最开始是想修改伪元素的样式来实现 然后发现伪元素的样式不能通过 js 来修改 因为系统名对应的颜色值是后台返回的 所以只能换种方法 实现的思路是用新加的 label 标签替换掉默认的 input 多选框

    2026年3月18日
    2
  • gg修改器如何使用修改迷你世界_gg游戏修改器迷你世界

    gg修改器如何使用修改迷你世界_gg游戏修改器迷你世界gg修改器脚本大全迷你世界设置回点发布时间:2020-08-20来源:脚本之家点击:->Imail的所有邮局信息,比如用户,密码都实际上都是存储在计算机注册表当中的,所以只需要打开注册表就可以看到Imail里的所有信息,包括用户的密码.细节:Imail将企业邮局信息全部存储在:HKEY_LOCAL_MACHINE\SOFTWARE\Ipswitch\IMail\Domains\\U…

    2025年9月15日
    8
  • ffmpeg源码编译_开源代码平台

    ffmpeg源码编译_开源代码平台 注:本文来转自http://www.aurora-x.net/wiki/CompileFFmpegWindows,前段时间用ffempg和x264开发了h264编码和解码的Filter,这篇文章是我编译ffmeg工程从网上搜到的最好的一份文档,及其详尽,我就是按照这个文档的一步一步地来做,第一次就顺利地完成了ffmepg的编译。如果你也在学习ffmpeg,来仔细学习一下这份文档吧,以后

    2026年3月9日
    4
  • 云服务器搭建青龙面板每日自动拿京豆

    云服务器搭建青龙面板每日自动拿京豆前言:之前网上有只要扫码一下就可以每天领上百京豆和一些红包的活动,后来呢,扫码就失效了,但是呢,这背后的技术还没有失效。这白嫖活动其实就是用脚本代替我们去参与京东的各种活动,去获取红包和京豆,而这些脚本是部署在电脑上,定时去执行的,接下来,根据网上的大佬的教程,我们也来实现一下。每天100-200京豆不等,坐收渔利,快来试试吧。一、安装前的准备​青龙面板是使用Docker来安装的,理论上,只要有可以运行Docker的电脑都可以进行安装。但是呢,因为脚本要定时运行,所以最好安装在服务器上,或

    2022年10月14日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号