Hessian

简介

Hessian是一个由Caucho公司开发的轻量级二进制RPC协议,使用简单的方法提供了RMI的功能。相比WebService,Hessian更简单、快捷。Hessian采用的是二进制RPC协议,所以它很适合于发送二进制数据。

Hessian可通过Servlet提供远程服务,需要将url请求映射到Hessian服务,也可与SpringMVC框架整合,通过它的 DispatcherServlet可将匹配的url请求转发到Hessian服务。Hessian的RPC功能完全使用动态代理来实现的,建议采用面向接口编程,通过接口暴露Hessian服务。类似的框架有DUBBOSOFA

常见问题

  1. 控制台警告
    1
    2
    警告: Hessian/Burlap: 'java.lang.Enum' is an unknown class...
    java.lang.RuntimeException: Class java.lang.Enum is not an enum.

解决办法:把两个项目与Hessian相关类的包名保持一致

  1. Hessian上传

    1
    2
    3
    4
    5
    6
    public interface UploadService {

    // 注意:使用Hessian时需要把inputStream参数放在最后
    void upload(String path, InputStream inputStream);

    }
  2. Hessian下载

    1
    2
    3
    4
    5
    public interface DownloadService {

    InputStream download(String filename);

    }

下载时如果遇到以下问题,则可能是由Hessian的一个Bug导致的

1
2
3
4
5
6
7
8
9
10
java.io.IOException: stream is closed
at sun.net.www.http.ChunkedInputStream.ensureOpen(ChunkedInputStream.java:174)
at sun.net.www.http.ChunkedInputStream.read(ChunkedInputStream.java:673)
at java.io.FilterInputStream.read(FilterInputStream.java:133)
at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3066)
at com.caucho.hessian.io.Hessian2Input.readBuffer(Hessian2Input.java:2783)
at com.caucho.hessian.io.Hessian2Input.read(Hessian2Input.java:2729)
at com.caucho.hessian.io.Hessian2Input$ReadInputStream.read(Hessian2Input.java:2917)
at java.io.InputStream.read(InputStream.java:101)
...

解决办法:覆盖Hessian包中的HessianProxy类(不建议直接修改源代码后重新打包),添加如下代码:

1
2
3
4
5
6
7
Object value = in.readReply(method.getReturnType());
// 以下是需要添加的Patch Code
if (value instanceof InputStream) {
value = new ResultInputStream(conn, is, in, (InputStream) value);
is = null;
conn = null;
}

此外,还需要在项目的pom.xml中添加如下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>generate-sources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<version>${hessian.version}</version>
<type>jar</type>
<overWrite>true</overWrite>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<excludes>**/HessianProxy.class</excludes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<packagingExcludes>WEB-INF/lib/hessian-${hessian.version}.jar</packagingExcludes>
</configuration>
</plugin>
</plugins>
</build>