原文链接点这里
Hessian 是一个用于连接网络服务的二进制协议,他的com.caucho.hessian.client 和 com.caucho.hessian.server包不依赖于任何其他Resin的类(Resin是caucho公司的一个很快的Web服务器,Hessian是他的一部分),因此他能够应用于更小的客户端,比如Java Applet。其实也是因为不依赖所以也可以在任何容器比如Tomcat,Jetty中很方便的使用。
因为他是一个短小的协议,它能够应用于手机端,来连接Resin这样的web服务器。 因为它比较精悍,因此他能够使用在EJB中。
就算Hessian规范内容的本身,也是短小而令人关注的。 这个是说很多通讯框架其实都可以使用这个规范来序列化及反序列化类。
Hessian Client
从一个Java客户端使用Hessian服务就像调用一个方法。 HessianProxyFactory创建的代理可以看为一个普通的Java对象,只不过这个对象有可能在远程连接错误的时候抛出协议异常。
HessianProxyFactory依赖于JDK1.3及以上版本。
每一个服务将有一个Java接口用于描述这个服务。下面的这个Hello ,World 示例仅仅返回了String, 因为Hessian支持Java的序列化,一次直接使用Java的类型。
//API for Basic service
package example;
public interface Basic {
public String hello();
}
下面是一个单独的Hessian Client, 这个Client创建了HessianProxyFactory, 客户端使用Factory根据给定的URL及Java
API接口创建一个Stub. 这个存根是一个该Java API的实现类。
// Hessian Client for Basic service
package example;
import com.caucho.hessian.client.HessianProxyFactory;
public class BasicClient {
public static void main(String []args)
throws Exception
{
String url = "http://www.caucho.com/hessian/test/basic";
HessianProxyFactory factory = new HessianProxyFactory();
Basic basic = (Basic) factory.create(Basic.class, url);
System.out.println("Hello: " + basic.hello());
}
}
这样就够了,不需要任何额外的操作了。服务还可以添加其他的方法,其可以包含任何Java类型的返回值,或者是任何Java类型的参数。
Hessian Service
虽然大多数的Hessian服务都将使用Resin-CMP 和 Resin-EJB,已充分利用EJB的优点。 但是Hessian库使得它能够通过HessianServlet进行扩展。
任何共有的方法都会识别为一个服务方法,因此创建服务方法跟写一个普通的方法是一样的。
因为服务是使用Servlet来实现的,因此可以像普通的Servlet一样使用ServletContext中的内容。
//Hello Service
package example;
public class BasicService implements Basic {
private String _greeting = "Hello, world";
public void setGreeting(String greeting)
{
_greeting = greeting;
}
public String hello()
{
return _greeting;
}
}
在Resin3.0中的配置:
<web-app xmlns="http://caucho.com/ns/resin">
<servlet servlet-name="hello"
servlet-class="com.caucho.hessian.server.HessianServlet">
<init>
<home resin:type="example.BasicService">
<greeting>Hello, world</greeting>
</home>
<home-api>example.Basic</home-api>
</init>
</servlet>
<servlet-mapping url-pattern="/hello"
servlet-name="hello"/>
</web-app>
通用的web.xml的配置:
<web-app>
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class>
<init-param>
<param-name>home-class</param-name>
<param-value>example.BasicService</param-value>
</init-param>
<init-param>
<param-name>home-api</param-name>
<param-value>example.Basic</param-value>
</init-param>
</servlet>
<servlet-mapping>
<url-pattern>/hello</url-pattern>
<servlet-name>hello</servlet-name>
</servlet-mapping>
</web-app>
Hessian Serialization
Hessian类可以被用来做序列化和反序列化。
应用程序使用Hessian来做序列化是很高效的。
//Serialization
Object obj = ...;
OutputStream os = new FileOutputStream("test.xml");
Hessian2Output out = new Hessian2Output(os);
out.writeObject(obj);
os.close();
// Deserialization
InputStream is = new FileInputStream("test.xml");
Hessian2Input in = new Hessian2Input(is);
Object obj = in.readObject(null);
is.close();
当序列化的接口比简单类型和String更负责的时候请确保该类实现了java.io.Serializable接口。
Hessian with large binary data
当应用程序想需要传输大量的二进制数据时,可以使用流来避免创建很大的字节数组。
只有方法的最后一个参数可以是InputStream,因为数据食杂方法调用的时候读取的。
例如,一个文件下载服务器也是可以有效的使用Hessian来搭建的
在下面的例子中,用户需要直接的控制Hessian协议,因为在方法返回前需要缓存这个文件。
// file upload API
package example;
public interface Upload {
public void upload(String filename, InputStream data);
}
如果返回值是一个InputStream, 那么在finally块中调用InputStream.close()是非常必要的,
因为在所有数据读取完且关闭Stream前,Hessian不会关闭底层的Httpstream.
// file download API
package example;
public interface Download {
public InputStream download(String filename, InputStream data);
}
// Download Java Code
InputStream is = fileProxy.download("test.xml");
try {
... // read data here
} finally {
is.close();
}
Hessian Debugging
Hessian Debug功能需要3.1.3或者更高版本
开启Hessian Servlet Debug拢共需要两步。首先,"debug" init-param必须设置在web.xml中,HessianServlet的日志级别必须为fine.Resin上的配置如下:
resin-web.xml enabling debugging
<web-app xmlns="http://caucho.com/ns/resin">
<servlet-mapping url-pattern="/my-bean"
servlet-class="example.MyBean">
<init debug="true"/>
</servlet-mapping>
<log name="com.caucho.hessian.server" level="fine"
path="stdout:"/>
</web-app>
日志内容:
sample debugging output
public class MyBean extends HessianServlet {
public example.Combine combine(String a, String b)
}
[2007/05/08 02:51:31.000] call 2.0
[2007/05/08 02:51:31.000] method "combine"
[2007/05/08 02:51:31.000] "hello"
[2007/05/08 02:51:31.000] "world"
[2007/05/08 02:51:31.000] reply 2.0
[2007/05/08 02:51:31.000] /* defun example.Combine [a, b] */
[2007/05/08 02:51:31.000] object example.Combine (#1)
[2007/05/08 02:51:31.000] a: "hello"
[2007/05/08 02:51:31.000] b: "world"
Hessian Streaming
Hessian3.1.3介绍了流API, 客户端可以使用流API发送周期性数据,例如在Comet-style显存监控项目中持续接收数据
// Streaming
import com.caucho.hessian.io.*;
void send(OutputStream os)
{
Hessian2StreamingOutput out;
out = new Hessian2StreamingOutput(os);
Object data;
while ((data = getNextChunk()) != null) {
out.writeObject(data);
}
out.close();
}
Hessian Client for a cell-phone
Hessian甚至能够使用在小型Java设备中,通过如下的类,Hessian能够在J2ME中进行使用:
- MicroHessianInput
- MicroHessianOutput
- HessianRemote
- HessianServiceException
- HessianProtocolException
下面的代码示例了使用手机作为一个客户端:
// Hello, world
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
...
MicroHessianInput in = new MicroHessianInput();
String url = "http://www.caucho.com/hessian/test/basic";
HttpConnection c = (HttpConnection) Connector.open(url);
c.setRequestMethod(HttpConnection.POST);
OutputStream os = c.openOutputStream();
MicroHessianOutput out = new MicroHessianOutput(os);
out.call("hello", null);
os.flush();
is = c.openInputStream();
MicroHessianInput in = new MicroHessianInput(is);
Object value = in.readReply(null);