分布式系统开发工具包 —— 基于 Hessian 的 HTTP RPC 调用技术

caucho

Hessian 官网:http://hessian.caucho.com/

hessian 是二进制 web service 协议。

Hessian 介绍

创建 Hessian 服务包括四个步骤:

  1. 创建 Java 接口,用于提供公开服务
  2. 使用 HessianProxyFactory 创建客户端
  3. 创建服务实现类
  4. 在 servlet 引擎中配置服务

HelloWorld 服务

1
2
3
public interface BasicAPI {
public String hello();
}

服务实现

1
2
3
4
5
6
7
8
9
10
11
12
13
public class BasicService extends HessianServlet implements BasicAPI {
private String _greeting = "Hello, world";

public void setGreeting(String greeting)
{
_greeting = greeting;
}

public String hello()
{
return _greeting;
}
}

客户端实现

1
2
3
4
5
6
String url = "http://hessian.caucho.com/test/test";

HessianProxyFactory factory = new HessianProxyFactory();
BasicAPI basic = (BasicAPI) factory.create(BasicAPI.class, url);

System.out.println("hello():" + basic.hello());

部署标准 web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<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 序列化

Hessian 类可以用来做序列化与反序列化

序列化

1
2
3
4
5
6
7
Object obj = ...;

OutputStream os = new FileOutputStream("test.xml");
Hessian2Output out = new Hessian2Output(os);

out.writeObject(obj);
os.close();

反序列化

1
2
3
4
5
InputStream is = new FileInputStream("test.xml");
Hessian2Input in = new Hessian2Input(is);

Object obj = in.readObject(null);
is.close();

如果要序列化比基础类型或 String 类型更加复杂的 java 对象,务必确保对象实现了 java.io.Serializable 接口。

Hessian 处理大量数据

分布式应用需要发送大量二进制数据时,使用 InputStream 会更加有效率,因为它避免了分配大量 byte 数组。方法
参数中只有最后一个参数可能是 InputStream,因为数据是在调用过程中读的。

下面是一个上传文件的 API 的例子

1
2
3
4
5
package example;

public interface Upload {
public void upload(String filename, InputStream data);
}

如果返回结果是 InputStream,客户端必须在 finally 块中调用 InputStream.close()方法,因为 Hessian 不会关闭
底层 HTTP 流,直到所有数据被读取并且 input stream 被关闭。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
文件下载 API:
package example;

public interface Download {
public InputStream download(String filename, InputStream data);
}

文件下载实现:
InputStream is = fileProxy.download("test.xml");

try {
... // read data here
} finally {
is.close();
}