Hessian实现Webservice 2011-04-26 09:13 sjsky ITEYE博客 字号:T | T 一键收藏,随时查看,分享好友! Hessian是一个轻量级的remoting on http工具,采用的是Binary RPC协议,所以它很适合于发送二进制数据,同时又具有防火墙穿透能力。 AD:WOT2014:用户标签系统与用户数据化运营培训专场 Hessian是一个轻量级的remoting on http工具,同时又具有防火墙穿透能力。Hessian一般是通过Web应用来提供服务,因此非常类似于平时我们用的WebService。只是它不使用SOAP协议,但相比webservice而言更简单、快捷。 Hessian官网:http://hessian.caucho.com/ Hessian可通过Servlet提供远程服务,需要将匹配某个模式的请求映射到Hessian服务。也可Spring框架整合,通过它的dispatcherServlet可以完成该功能,dispatcherServlet可将匹配模式的请求转发到Hessian服务。Hessian的server端提供一个servlet基类,用来处理发送的请求,而Hessian的这个远程过程调用,完全使用动态代理来实现的,,建议采用面向接口编程,Hessian服务通过接口暴露。 Hessian处理过程示意图: 客户端——>序列化写到输出流——>远程方法(服务器端)——>序列化写到输出流 ——>客户端读取输入流——>输出结果 下面详细介绍最常用的两种方式实现Hessian提供webservice: 纯Hessian实现 配合Spring框架实现 在开始之前当然需要到官网上下载相关的lib包,放入项目的/WEB-INF/lib/下 【一】、纯Hessian实现步骤: 1.基本代码 首先编写一个服务的接口类:HelloHessian.java Java代码 package michael.hessian; import java.util.List; import java.util.Map; /** * @author michael * */ public interface HelloHessian { String sayHello(); MyCar getMyCar(); List myloveFruit(); Map myBabays(); } 一个java bean文件MyCar.java: Java代码 package michael.hessian; import java.io.Serializable; /** * @author michael * */ public class MyCar implements Serializable { /** * */ private static final long serialVersionUID = 4736905401908455439L; private String carName; private String carModel; /** * @return the carName */ public String getCarName() { return carName; } /** * @return the carModel */ public String getCarModel() { return carModel; } /** * @param pCarName the carName to set */ public void setCarName(String pCarName) { carName = pCarName; } /** * @param pCarModel the carModel to set */ public void setCarModel(String pCarModel) { carModel = pCarModel; } /** * @see java.lang.Object#toString() * @return */ @Override public String toString() { return "my car name:[" + this.carName + "] model:[" + this.carModel + "]."; } } 服务端接口的实现类:HelloHessianImpl.java Java代码 package michael.hessian.impl; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import michael.hessian.HelloHessian; import michael.hessian.MyCar; /** * @author michael * */ public class HelloHessianImpl extends HessianServlet implements HelloHessian { public MyCar getMyCar() { MyCar car = new MyCar(); car.setCarName("阿斯顿·马丁"); car.setCarModel("One-77"); return car; } public Map myBabays() { Map map = new HashMap(); map.put("son","孙吴空"); map.put("daughter","孙小美"); return map; } public List myloveFruit() { List list = new ArrayList(); list.add("apple"); list.add("kiwi"); list.add("orange"); return list; } public String sayHello() { return "welcom to Hessian"; } } 2.配置文件web.xml修改 在web.xml配置文件里增加如下信息: Xml代码 <servlet> <servlet-name>HelloHessianservlet-name> <servlet-class> com.caucho.hessian.server.HessianServlet servlet-class> <init-param> <param-name>home-classparam-name> <param-value>michael.hessian.impl.HelloHessianImplparam-value> init-param> <init-param> <param-name>home-apiparam-name> <param-value>michael.hessian.HelloHessianparam-value> init-param> <load-on-startup>1load-on-startup> servlet> <servlet-mapping> <servlet-name>HelloHessianservlet-name> <url-pattern>/HessianServiceurl-pattern> servlet-mapping> <servlet-mapping> 3.java客户端验证 Java代码 package michael.hessian.client; import java.net.MalformedURLException; import java.util.Map; import michael.hessian.HelloHessian; import michael.hessian.MyCar; import com.caucho.hessian.client.HessianProxyFactory; /** * @author michael * */ public class HessianClientTest { /** * @param args */ public static void main(String[] args) { String url = "http://localhost:8082/J2EE_sjsky/HessianService"; HessianProxyFactory factory = new HessianProxyFactory(); try { HelloHessian hello = (HelloHessian) factory.create( HelloHessian.class,url); System.out.println(hello.sayHello()); MyCar car = hello.getMyCar(); System.out.println(car.toString()); for (Map.Entry entry : hello.myBabays().entrySet()) { System.out.println(entry.getKey() + " " + entry.getValue()); } for (String str : hello.myloveFruit()) { System.out.println(str); } } catch (MalformedURLException e) { e.printstacktrace(); } } } 运行结果如下: Java代码 welcom to Hessian my car name:[阿斯顿·马丁] model:[One-77]. daughter 孙小美 son 孙吴空 apple kiwi orange 【二】、spring+hessian 实现服务端: 1.基本代码见上面的demo 2.修改配置文件 在web.xml,增加内容如下: Xml代码 <servlet> <servlet-name>springhessianservlet-name> <servlet-class> org.springframework.web.servlet.dispatcherServlet servlet-class> <bean name="/helloHessianService" class="org.springframework.remoting.caucho.HessianServiceExporter"> <property name="service" ref="helloHessianImpl" /> <property name="serviceInterface" value="michael.hessian.HelloHessian" /> bean> beans> 3.java客户端验证 和上面的例子相似,只需要把访问的url替换成新的即可如下: Java代码 String url=http://localhost:8082/J2EE_sjsky/springhessian/helloHessianService 运行结果和上面例子一样。 4.spring配置客户端 增加一个spring的bean配置文件hessian-client.xml Xml代码 xml version="1.0" encoding="UTF-8"?> > <beans> <bean id="helloHessianClient" class="org.springframework.remoting.caucho.HessianProxyfactorybean"> <property name="serviceUrl"> <value> http://localhost:8082/J2EE_sjsky/springhessian/helloHessianService value> property> <property name="serviceInterface" value="michael.hessian.HelloHessian" /> bean> beans> 测试代码HessianspringClient.java: Java代码 package michael.hessian.client; import java.util.Map; import michael.hessian.HelloHessian; import michael.hessian.MyCar; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClasspathXmlApplicationContext; /** * @author michael * */ public class HessianspringClient { /** * @param args */ public static void main(String[] args) { try { ApplicationContext context = new ClasspathXmlApplicationContext( "hessian-client.xml"); HelloHessian hello = (HelloHessian) context .getBean("helloHessianClient"); System.out.println(hello.sayHello()); MyCar car = hello.getMyCar(); System.out.println(car.toString()); for (Map.Entry entry : hello.myBabays().entrySet()) { System.out.println(entry.getKey() + " " + entry.getValue()); } for (String str : hello.myloveFruit()) { System.out.println(str); } } catch (Exception e) { e.printstacktrace(); } } } 运行结果和上面完全一致。 5.com.caucho.hessian.io.HessianProtocolException: expected string at 0x6d异常处理 我在spring+hessian整合测试过程中,客户端调用时,发生了异常,而服务端错误内容如下: Java代码 2011-4-25 16:14:44 org.apache.catalina.core.StandardWrapperValve invoke 严重: Servlet.service() for servlet remoting threw exception com.caucho.hessian.io.HessianProtocolException: expected string at 0x6d at com.caucho.hessian.io.Hessian2Input.error(Hessian2Input.java:2882) at com.caucho.hessian.io.Hessian2Input.expect(Hessian2Input.java:2830) at com.caucho.hessian.io.Hessian2Input.readString(Hessian2Input.java:1362) at com.caucho.hessian.io.Hessian2Input.readMethod(Hessian2Input.java:272) at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:249) at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:221) at org.springframework.remoting.caucho.Hessian2SkeletonInvoker.invoke(Hessian2SkeletonInvoker.java:67) at org.springframework.remoting.caucho.HessianServiceExporter.handleRequest(HessianServiceExporter.java:147) at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:49) at org.springframework.web.servlet.dispatcherServlet.dodispatch(dispatcherServlet.java:819) at org.springframework.web.servlet.dispatcherServlet.doService(dispatcherServlet.java:754) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:399) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:364) at javax.servlet.http.HttpServlet.service(HttpServlet.java:710) at javax.servlet.http.HttpServlet.service(HttpServlet.java:803) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:261) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:581) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447) at java.lang.Thread.run(Thread.java:619) 经查资料发现原始是hessian和spring的版本不兼容引起的,重新下载hessian-3.1.6.jar导入项目,一起运行正常,测试完全通过。 测试结果显示,几种协议的通讯效率依次为: RMI > httpinvoker >= Hessian >> Burlap >> web service RMI不愧是JAVA的首选远程调用协议,非常高效稳定,特别是在大数据量的情况下,与其他通讯协议的差距尤为明显。 httpinvoker使用java的序列化技术传输对象,与RMI在本质上是一致的。从效率上看,两者也相差无几,httpinvoker与RMI的传输时间基本持平。 Hessian在传输少量对象时,比RMI还要快速高效,但传输数据结构复杂的对象或大量数据对象时,较RMI要慢20%左右。 Burlap仅在传输1条数据时速度尚可,通常情况下,它的毫时是RMI的3倍。 Web Service的效率低下是众所周知的,平均来看,Web Service的通讯毫时是RMI的10倍。 1. 下载Spring[2.56]包和Hessian[3.1.6包 remoting-servlet.xml配置如下: Java代码 收藏代码 <bean id="hello" class="com.module.impl.HelloImpl"/> <bean name="/Hello" class="org.springframework.remoting.caucho.HessianServiceExporter"> <!— Hessian服务的实现类--> <property name="service" > <ref bean="hello" /> </property> <!-- Hessian服务的接口--> <property name="serviceInterface" value="com.module.Hello"/> </bean>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。