Design Goals

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:

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.

null

null values are allowed in place of any string, xml,
binary, list, map, or remote.

null

null ::= N

boolean

The byte 'F' represents false and the byte 'T'
represents true.

boolean ::= T
::= F

boolean true

T

int

A 32-bit signed integer. An integer is represented by the
byte 'I' followed by the 4-bytes of the integer in big-endian
order

int ::= I b32 b24 b16 b8

integer 300

I x00 x00 x01 x2c

long

A 64-bit signed integer. An long is represented by the
byte 'L' followed by the 8-bytes of the integer in big-endian order

long ::= L b64 b56 b48 b40 b32 b24 b16 b8

long 300

L x00 x00 x00 x00 x00 x00 x01 x2c

double

A 64-bit IEEE floating pointer number.

double ::= D b64 b56 b48 b40 b32 b24 b16 b8

double 12.25

D x40 x28 x80 x00 x00 x00 x00 x00

date

Date represented by a 64-bits long of milliseconds since the epoch.

date ::= d b64 b56 b48 b40 b32 b24 b16 b8

2:51:31 May 8, 1998

d x00 x00 x00 xd0 x4b x92 x84 xb8

string

A 16-bit unicode character string encoded in UTF-8.
Strings are encoded in chunks. 'S' represents the final chunk
and 's' 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 ::= (s b16 b8 utf-8-data)* S b16 b8 utf-8-data

"Hello" string

S x00 x05 hello

xml

An XML document encoded as a 16-bit unicode character
string encoded in UTF-8.
XML data is encoded in chunks. 'X' represents the final chunk
and 'x' 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.

xml ::= (x b16 b8 utf-8-data)* X b16 b8 utf-8-data

trivial XML document

X x00 x10 <top>hello</top>

Note

Because this document does not define the language mapping,
implementations are free to return a string when reading an xml
entity.

binary

A binary value.

Binary data is encoded in chunks. 'B' represents the final chunk
and 'b' represents any initial chunk. Each chunk has a 16-bit
length value.

binary ::= (b b16 b8 binary-data)* B b16 b8 binary-data

list

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.

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

Each list item is added to the reference list to handle
shared and circular elements. See the
ref element.

The valid values of type are 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 type
information to instantiate the specific array type.
On the other hand, a Perl server would likely ignore the contents of type
entirely and create a generic array.

map

Represents serialized objects and Maps. The type
element describes the type of the map. Objects are represented by a
map from field names to their values and type is the class
of the object itself.

map ::= M t b16 b8 type-string (object, object)* z

The type may 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.

Each map is added to the reference list. Any time the
parser expects a map, it must also be able to support a
null or a ref.

The type is chosen by the service. Often it may be the
Java classname describing the service.

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 ::= R b32 b24 b16 b8

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 <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'.

Call

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.

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

obj.add2(2,3) call

c x01 x00
m x00 x04 add2
I x00 x00 x00 x02
I x00 x00 x00 x03
z

obj.add2(2,3) reply

r x01 x00
I x00 x00 x00 x05
z

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:

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

http://hostname/hessian 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.

/ejb-name, 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 ejb-name
corresponds to the ejb-name in the deployment descriptor.

object-id 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.

Example Entity Home Identifier

http://localhost/hessian/my-entity-bean

Example Entity Bean Identifier

http://localhost/hessian/my-entity-bean?ejbid=slytherin

Example Session Home Identifier

http://localhost/hessian/my-session-bean

Example Session Bean Identifier

http://localhost/hessian/my-session-bean?ejbid=M9Zs1Zm

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 with _hessian_ are reserved.

Servers should accept calls with either the mangled method name
or the unmangled method name. Clients should send the mangled method name.

Versioning

Reply

Value

A successful reply returns a single value and possibly
some header information.

integer 5 result

r x01 x00
I x00 x00 x00 x05
z

Faults

Failed calls return a fault.

Each fault has a number of informative fields, expressed like
<map> entries. The defined fields are code, message,
and detail. code is one of a short list of strings
defined below. message is a user-readable message.
detail is an object representing the exception. In Java,
detail will be a serialized exception.

Copyright and Licensing

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

changes in 1.0.2

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

Cloud-optimized Resin Server is a Java EE certified Java Application Server, and Web Server, and Distributed Cache Server (Memcached).Leading companies worldwide with demand for reliability and high performance web applications including SalesForce.com, CNET, DZone and many more are powered by Resin.