Hessian is a compact binary protocol for connecting web services.
Because Hessian is a small protocol, J2ME devices like cell-phones can use it to connect to Resin servers. Because it's powerful, it can be used for EJB services.
Hessian 2 is a compaction of the Hessian protocol. All Hessian 1 codes are understood by Hessian 2. The extended codes provide compact formats for common values, e.g. storing an integer zero as a single byte instead of Hessian 1's 5 bytes.
The Hessian home page contains the latest information about Hessian.
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.
Given the EJB environment, the Hessian protocol has the following requirements:
Hessian's object serialization has 9 primitive types:
It has 2 combining constructs:
Finally, it has 2 special contructs:
Null represents a null pointer.
The byterepresents the null pointer.
values are allowed in place of any , , , , , or .
The byterepresents false and the byte represents true.
A 32-bit signed integer. An integer is represented by the bytefollowed by the 4-bytes of the integer in big-endian order
Integers between -16 and 31 are represented by a single byte in the range x80 to xaf. The value of the integer is b0 - x90.
The integer zero is represented by x90, -1 is represented by x8f and 17 is represented by xa1
Integers between -2048 and 2047 are encoded in two bytes with the leading byte in the range xd0 to xdf. The value of the integer is 256 * (b0 - xd8) + b1.
The integer zero is represented by xd8 x00, -256 is represented by xd7 x00 and 513 is represented by xda x01
Integers between -262144 and 262143 are encoded in three bytes with the leading byte in the range x58 to x5f. The value of the integer is 65536 * (b0 - x5c) + 256 * b1 + b0.
The integer zero is represented by xd4 x00 x00, -65536 is represented by xd3 x00 x00 and 65537 is represented by xd5 x00 x01
A 64-bit signed integer. An long is represented by the bytefollowed by the 8-bytes of the integer in big-endian order
Longs between -8 and 15 are represented by a single byte in the range xd8 to xef. The value of the long is b0 - xe0.
The long zero is represented by xe0, -1 is represented by xdf and 15 is represented by xef
Longs between -2048 and 2047 are encoded in two bytes with the leading byte in the range xf0 to xff. The value of the long is 256 * (b0 - xf8) + b1.
The long zero is represented by xf8 x00, -256 is represented by xf7 x00 and 513 is represented by xfa x01
Longs between -262144 and 262143 are encoded in three bytes with the leading byte in the range x38 to x3f. The value of the long is 65536 * (b0 - x3c) + 256 * b1 + b0.
The long zero is represented by x3c x00 x00, -65536 is represented by x3b x00 x00 and 65537 is represented by x3d x00 x01
A 64-bit IEEE floating pointer number.
Date represented by a 64-bits long of milliseconds since the epoch, GMT.
A 16-bit unicode character string encoded in UTF-8. Strings are encoded in chunks.represents the final chunk and represents any initial chunk. Each chunk has a 16-bit length value.
The length is the number of characters, which may be different than the number of bytes.
String chunks may not split surrogate pairs.
Strings with length less than 15 may be encoded with a single length byte [x00-x0f].
An XML document encoded as a 16-bit unicode character string encoded in UTF-8. XML data is encoded in chunks.represents the final chunk and represents any initial chunk.
Each chunk has a 16-bit length value. The length is the number of characters, which may be different than the number of bytes.
Note: Because this document does not define the language mapping, implementations are free to return a string when reading anentity.
A binary value.
Binary data is encoded in chunks.represents the final chunk and represents any initial chunk. Each chunk has a 16-bit length value.
An ordered list, like an array. All lists have a type string, a length, a list of objects, and a trailing 'z'. The type string may be an arbitrary UTF-8 string understood by the service (often a Java class name, but this isn't required.) The length may be -1 to indicate that the list is variable length.
Eachitem is added to the reference list to handle shared and circular elements. See the element.
Any parser expecting amust also accept a or a shared .
Note: The valid values ofare not specified in this document and may depend on the specific application. For example, a Java EJB server which exposes an Hessian interface can use the information to instantiate the specific array type. On the other hand, a Perl server would likely ignore the contents of entirely and create a generic array.
Hessian 2.0 allows a compact form of the list for successive lists of the same type where the length is known beforehand. The type and length are encoded by integers, where the type is a reference to an earlier specified type.
list ::= 'v'*
Represents serialized objects and Maps. Theelement describes the type of the map. Objects are represented by a map from field names to their values and is the class of the object itself.
Themay be empty, i.e. a zero length. The parser is responsible for choosing a type if one is not specified. For objects, unrecognized keys will be ignored.
Eachis added to the reference list. Any time the parser expects a , it must also be able to support a or a .
Note: Theis chosen by the service. Often it may be the Java classname describing the service.
Hessian 2.0 has a compact object form where the field names are only serialized once. Following objects only need to serialize their values
The object definition includes a manadatory type string, the number of fields, the field names, and the values for the first object. The first integer is the length of the type string.
The object instantiation creates a new object based on a previous definition.
The integer is a reference to the object definition.
An integer referring to a previousor instance. As each or is read from the input stream, it is assigned the integer position in the stream, i.e. the first or is '0', the next is '1', etc. A later can then use the previous object. Writers are not required to generate , but parsers must be able to recognize them.
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 eachand to an array as it's read. The will return the corresponding object from the array. To support circular structures, the implementation would store the or immediately, before filling in the object's contents.
Each <list> or <array> is stored into an array as it is parsed. <ref> selects one of the stored objects. The first object is numbered '0'.
Note:only refers to and elements. and , in particular, will only share references if they're wrapped in a or .
A reference to a remote object. The remote has aand a utf-8 string representing the object's URL.
A Hessian call invokes a method on an object with an argument list. The object is specified by the container, e.g. for a HTTP request, it's the HTTP URL. The arguments are specified by Hessian serialization.
Object Naming (non-normative)
URLs are flexible enough to encode object instances as well as simple static service locations. The URL uniquely identifies the Hessian object. Thus, Hessian can support object-oriented services, e.g. naming services, entity beans, or session beans, specified by the URL without requiring extra method parameters or headers.
Object naming may use the query string convention that "?id=XXX" names the object "XXX" in the given service. This convention is recommented, but not required.
For example, a stock quote service might have a factory interface like http://foo.com/stock and object instances like http://foo.com?id=PEET. The factory interface would return valid object references through the factory methods.
Object naming (non-normative)
As an example, the following format is used for EJB:
identifies the EJB container. In Resin-EJB, this will refer to the EJB Servlet. "/hessian" is the servlet prefix (url-pattern.) HTTP is just used as an example; Hessian does not require the use of HTTP.
, the path info of the request, identifies the EJB name, specifically the home interface. EJB containers can contain several entity and session beans, each with its own EJB home. The corresponds to the ejb-name in the deployment descriptor.
identifies the specific object. For entity beans, the object-id encodes the primary key. For session beans, the object-id encodes a unique session identifier. Home interfaces have no ";ejbid=..." portion.
Methods and Overloading
Method names must be unique. Two styles of overloading are supported: overloading by number of argumetns and overloading by argument types. Overloading is permitted by encoding the argument types in the method names. The types of the actual arguments must not be used to select the methods.
Method names beginning withare reserved.
Servers should accept calls with either the mangled method name or the unmangled method name. Clients should send the mangled method name.
Note: See the Java binding for a possible overloading scheme.
Arguments immediately follow the method in positional order. Argument values use Hessian's serialization.
All arguments share references, i.e. the reference list starts with the first argument and continues for all other arguments. This lets two arguments share values.
The number and type of arguments are fixed by the remote method. Variable length arguments are forbidden. Implementations may take advantage of the expected type to improve performance.
Headers are (string, object) pairs that preceed the arguments.
The value of the header can be any serialized object.
For example, a request might include a transaction context in a header.
The call and response tags include a major and minor byte. The current version is 1.0.
A successful reply returns a single value and possibly some header information.
Failed calls return a.
Each fault has a number of informative fields, expressed like <map> entries. The defined fields are, , and . is one of a short list of strings defined below. is a user-readable message. is an object representing the exception. In Java, will be a serialized exception.
Metadata is handled by special method calls, methods beginning with.
returns a string. The following attributes are predefined by this spec:
"java.api.class" returns the client proxy's Java API class for the current URL. "java.home.class" returns the API class for the factory URL, i.e. without any "?id=XXX" query string. "java.object.class" returns the API class for object instances.
In the case of services with no object instances, i.e. non-factory services, all three attributes will return the same class name.
A "Micro Hessian" implementation may omit support for the "double" type.
Any party may implement this protocol for any purpose without royalty or license fee, provided that the implementation conforms to this specification. Caucho Technology reserves the right to create a test suite, freely available without royalty or license fee, to validate implementation conformance. The limited permissions granted herein are perpetual and may not be revoked by Caucho Technology or its successors or assigns.
This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and these paragraphs are included on all such copies and derivative works.
This document and the information contained herein is provided on an "AS IS" basis and CAUCHO TECHNOLOGY DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
changes in 1.0.2
changes in 1.0
changes in V3
changes in V2