最近在项目中接触到了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 [email protected] * @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("[email protected]"); Person resultBean = iPersonServer.getPerson(person); System.out.println(resultBean.getUserId() + "\t" + resultBean.getUserName()); } catch (MalformedURLException e) { e.printStackTrace(); } } }
源代码见附件!
后记:
把Hession用于移动发现,客户端可以直接调用服务端的方法非常方便!