一、什么是hessian
hessian 是一个基于binary-RPC 实现的远程通讯library。
使用二进制传输数据。
hessian 通常通过Web应用来提供服务,通过接口暴露。
Servlet 和 Spring的DispatcherServlet都可以把请求转发给Hessian服务。
由以下两种方式提供:
com.caucho.hessian.server.HessianServlet。
org.springframework.web.servlet.DispatcherServlet。
关于hessian的问题:
1、是基于什么协议实现的
基于Binary-RPC协议实现的。
2、怎么发起请求?
通过hessian本身提供的API来发起请求。
3、怎样将请求转化为符合协议格式的?
hessian通过其自定义的串行化机制将请求信息进行序列化,产生二进制流。
4、使用什么传输协议传输?
hessian基于Http协议进行传输。
5、响应端基于什么机制来接收请求?
响应端根据hessian提供的API来接收请求。
6、怎么讲流还原为传输格式?
hessian根据其私有的串行化机制来将请求信息进行反序列化,传递给使用者 时已是相应的请求信息对象了。
7、处理完毕后怎么回应?
处理完毕后直接返回,hessian将结果对象进行序列化,传输至调用端。
二、Hessian的优缺点
缺点:
缺乏安全机制,传输没有加密
异常机制不完善,总是报一些错误,错误原因也是很多,提示信息不足。
事务处理欠缺
版本问题,(我自己在项目中使用的是hessian-3.1.3.jar)
优点:
简单易用,面向接口,通过接口暴露服务,不需要配置防火墙效率高,复杂对象序列化速度仅次于RMI,简单对象序列化优于RMI,二进制传输多语言支持:wiki、java、Flash/Flex、Python、C++、.NET C# 、PHP等
可与Spring集成,配置简单
HessianProxy 类的:
invoke(Object proxy, Method method, Object []args){
String methodName = method.getName();// 取得方法名
Object value = args[0]; // 取得传入参数
conn = sendRequest(mangleName, args) ; // 通过该方法和服务器端取得连接
httpConn = (HttpURLConnection) conn;
code = httpConn.getResponseCode(); // 发出请求
// 等待服务器端返回相应…………
InputStream is = conn.getInputStream();
AbstractHessianInput in = _factory.getHessianInput(is); //转化为hessian自己的输入输出API
Object value = in.readObject(method.getReturnType()); // 取得返回值
}
URLConnection sendRequest(String methodName, Object []args){
URLConnection conn = _factory.openConnection(_url); // 创建 URLConnection
OutputStream os = conn.getOutputStream();
AbstractHessianOutput out = _factory.getHessianOutput(os); // 封装为 hessian 自己的输入输出 API
out.call(methodName, args);
return conn;
}
2. 服务器端接收请求并处理请求
具体处理步骤如下:
a)HessianServiceExporter 类
(HessianExporter) invoke(request.getInputStream(), response.getOutputStream());
b)HessianExporter 类
(Hessian2SkeletonInvoker) this.skeletonInvoker.invoke(inputStream, outputStream);
c)Hessian2SkeletonInvoker 类
//将输入输出封转化为转化为 Hessian 特有的 Hessian2Input 和 Hessian2Output
Hessian2Input in = new Hessian2Input(isToUse);
in.setSerializerFactory(this.serializerFactory);
AbstractHessianOutput out = null;
int major = in.read();
out = new Hessian2Output(osToUse);
out.setSerializerFactory(this.serializerFactory);
(HessianSkeleton) this.skeleton.invoke(in, out);
d)HessianSkeleton 类
//读取方法名
String methodName = in.readMethod();
Method method = getMethod(methodName);
//读取方法参数
Class []args = method.getParameterTypes();
Object []values = new Object[args.length];
//执行相应方法并取得结果
result = method.invoke(service, values);
//结果写入到输出流
out.writeObject(result);
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Hessian在Spring中的工作流程如下:
(1)客户端:
a.发送远程请求:
客户端程序-->调用公共接口的方法-->Hessian拦截器拦截请求-->封装远程调用请求-->Hessian代理-->通过HTTP协议发送远程请求代理到服务端
b.接收远程调用响应:
远程调用结果-->HTTP响应-->客户端
(2)服务端:
a.接收远程调用请求:
HessianServiceExporter接收请求-->将远程调用对象封装为HessianSkeleton框架-->HessianSkeleton处理远程调用请求
b.返回远程调用响应:
HessianSkeleton封装远程调用处理结果-->HTTP响应-->客户端
下图是通过hessian一次完成调用的示意图
下面的代码是我自己在项目中用到的,大家可以参考,有更好的方法可以留言
SpringMVC 集成 Hessian
1、引用hessian-3.1.3.jar
2、新建一个hessian-servlet.xml
3、在web.xml 里面添加
<!-- Spring 请求分发控制器 -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:dispatcher-config.xml
</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
4、在dispatcher-config.xml 里面添加配置信息
这个文件里面根据你们自己的项目配置一些相关信息
下面是我根据集成hessian加入的配置信息
<mvc:annotation-driven />(一开始我自己没有加入spring自动的拦截器配置在测试的时候老是出现错误问题)
<!-- Action 映射地址 -->
<import resource="dispatcher-action.xml"/>
<import resource="hessian-servlet.xml"/>
5、hessian-servlet.xml 中的配置
<!-- 业务类 -->
<bean id="pointPayServiceImpl" class="com.point.web.service.PointPayServiceImpl"/>
<!-- 远程服务 -->
<bean name="hessianService" class="org.springframework.remoting.caucho.HessianServiceExporter">
<property name="service" ref="pointPayServiceImpl"/>
<property name="serviceInterface">
<value>
com.point.web.service.IPointPayService
</value>
</property>
</bean>
6、dispatcher-action.xml 配置
<!-- 配置url的mapping映射 -->
<bean id="simpleUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hessian/alipay">hessianService</prop>
</props>
</property>
</bean>
上面内容相当于Server端
客户端:
1、引用hessian-3.1.3.jar
2、在方法里面写
String payurl = "http://xxx:8080/demo/hessian/alipay";
HessianProxyFactory factory = new HessianProxyFactory();
//factory.setOverloadEnabled(true);
ITestService hessianService =( ITestService)factory.create( ITestService.class,payurl);
String message = hessianService.requestAlipay(param);
如果把客户端变成服务端配置
web.xml:
<servlet>
<servlet-name>DemoHessian</servlet-name>
<servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class>
<init-param>
<param-name>home-class</param-name>
<param-value>com.point.web.service.PointPayServiceImpl</param-value>
</init-param>
<init-param>
<param-name>home-api</param-name>
<param-value>com.point.web.service.IPointPayService</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DemoHessian</servlet-name>
<url-pattern>/hessianService</url-pattern>
</servlet-mapping>
需要注意的是:客户端和服务端 接口、实现类和POJO的路径必须一样