最近在项目中接触到了Hessian,发现这是一个比较好的东西。官方地址:http://www.caucho.com/hessian/
下面是网络上的一些说明资料:
相比WebService,Hessian更简单、快捷。采用的是二进制RPC协议(Binary),因为采用的是二进制协议,所以它很适合于发送二进制数据。Hessian通常通过Web应用来提供服务,因此非常类似于WebService。只是它不使用SOAP协议。
Hessian通过Servlet提供远程服务。需要将匹配某个模式的请求映射到Hessian服务。Spring的DispatcherServlet可以完成该功能,DispatcherServlet可将匹配模式的请求转发到Hessian服务。Hessian的server端提供一个servlet基类, 用来处理发送的请求,而Hessian的这个远程过程调用,完全使用动态代理来实现的,,推荐采用面向接口编程,因此,Hessian服务建议通过接口暴露。
Hessian处理过程示意图:
客户端——>序列化写到输出流——>远程方法(服务器端)——>序列化写到输出流 ——>客户端读取输入流——>输出结果
简单来说:
客户端拥有与服务器相同(兼容)的接口,客户端通过Hession请求就可以调用服务器的方法,客户端包括:Java,Objective C,Flex 等等
简单例子:
第一种配置方式(在Hession的Servlet中配置接口和现实类,服务器返回普通参数):
服务端
/**
* 服务器给客户端的暴露的接口
*
* @author ZhangMingxue
*
*/
public interface IHello {
public String sayHello();
}
/**
* 服务器实现有接口
*
* @author ZhangMingxue
*
*/
public class HelloImple implements IHello {
public String sayHello() {
return "Hello Hession !";
}
}
服务端的配置:在WEB-INF/web.xml添加
<servlet> <servlet-name>HelloServlet</servlet-name> <!-- Hession提供的Servlet --> <servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class> <init-param> <param-name>home-class</param-name> <!-- 服务器对接口的现实,供客户端调用 --> <param-value>com.mengya.imple.HelloImple</param-value> </init-param> <init-param> <param-name>home-api</param-name> <!-- 客户端接口 --> <param-value>com.mengya.inter.IHello</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/HelloServlet</url-pattern> </servlet-mapping>
客户端测试(本实例客端也是用Java):
public static void main(String[] args) {
// 服务器访问路径
String url = "http://127.0.0.1:8080/HessionDemos/HelloServlet";
HessianProxyFactory hessianProxyFactory = new HessianProxyFactory();
try {
// IHello是客户端的接口,与服务器接口一致(客户端的语言包括:Java,Objective C,Flex 等)
IHello iHello = (IHello) hessianProxyFactory.create(IHello.class,
url);
// 客户端调服务器的接口实现
System.out.println("Result == " + iHello.sayHello());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
以上就是一个简单的例子。服务器与客户端共用的接口是:IHello,服务器现实的接口是: HelloImple,客户端通过Hession根据客户端接口调用服务器方法并接受返回参数。经过测试,客户端与服务器端的接口不一定要一样!如下:
服务器端接口:
/**
* 服务器给客户端的暴露的接口
*
* @author ZhangMingxue
*
*/
public interface IHello {
public String sayHello();
public void clientNotMethod();
}
客户端接口:
/**
* 客户端与服务器相同(或兼容)的接口
*
* @author ZhangMingxue
*
*/
public interface IHello {
public String sayHello();
public String serverNotMehtod();
}
以上接口也可以在客户端通过IHello接口调用服务器的 sayHello()方法,不赞成这样,只是测试发现这样也可以调用。
第二种配置方式(继承Hession的Servlet,服务器返回Bean):
1、调用参数Bean与结果参数Bean
/**
* 客户端与服务端传输的JavaBean,必须Serializable
*
* @author ZhangMingxue
*
*/
public class Person implements Serializable {
private static final long serialVersionUID = 3400062242004002707L;
private String userId;
private String userName;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
服务端接口:
/**
* 服务端接口
*
* @author mingxue.zhang@163.com
* @company http://www.brilliance.com.cn
* @date 2013-4-14
* @version 1.0
* @JDK 1.5
*/
public interface IPersonServer {
public Person getPerson(Person bean);
}
服务端Servlet:
/**
* 服务端访问Servlet,继承HessianServlet并实现服务端接口
*
* @author ZhangMingxue
*
*/
public class PersonServlet extends HessianServlet implements IPersonServer {
private static final long serialVersionUID = -343120217079779622L;
/**
* 实现服务端接口的方法
*/
public Person getPerson(Person bean) {
System.out.println("客户端参数:" + bean.getUserId() + "\t"
+ bean.getUserName());
bean.setUserName("Server:" + bean.getUserName());
return bean;
}
}
服务端的配置:在WEB-INF/web.xml添加
<servlet> <servlet-name>PersonServlet</servlet-name> <servlet-class>com.mengya.servlet.PersonServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>PersonServlet</servlet-name> <url-pattern>/PersonServlet</url-pattern> </servlet-mapping>
客户端接口 与服务端接口一致(不一定是Java语言,接口名与接口的方法一致),客户端测试如下:
public class PersonTest {
public static void main(String[] args) {
// 服务器访问路径
String url = "http://127.0.0.1:8080/HessionDemos/PersonServlet";
HessianProxyFactory hessianProxyFactory = new HessianProxyFactory();
try {
// IHello是客户端的接口,与服务器接口一致(客户端的语言包括:Java,Objective C,Flex 等)
IPersonServer iPersonServer = (IPersonServer) hessianProxyFactory
.create(IPersonServer.class, url);
// 客户端调服务器的接口实现
Person person = new Person();
person.setUserId("1001");
person.setUserName("mingxue.zhang@163.com");
Person resultBean = iPersonServer.getPerson(person);
System.out.println(resultBean.getUserId() + "\t"
+ resultBean.getUserName());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
源代码见附件!
后记:
把Hession用于移动发现,客户端可以直接调用服务端的方法非常方便!