微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Hessian实现Webservice

Hessian是一个轻量级的remoting on http工具,采用的是Binary RPC协议,所以它很适合于发送二进制数据,同时又具有防火墙穿透能力。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代码

 
 
  1. package michael.hessian;     
  2. import java.util.List;     
  3. import java.util.Map;     
  4.     
  5. /**    
  6.  * @author michael    
  7.  *     
  8.  */    
  9. public interface HelloHessian {     
  10.     
  11.     String sayHello();     
  12.     
  13.     MyCar getMyCar();     
  14.     
  15.     List myloveFruit();     
  16.     
  17.     Map myBabays();     
  18.     
  19. }   

一个java bean文件MyCar.java:

package michael.hessian;     

  •     
  • import java.io.Serializable;     
  •     
  • 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    
  • void setCarName(String pCarName) {     
  •         carName = pCarName;     
  •     }     
  •     
  •          * @param pCarModel the carModel to set    
  • 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

    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;     
  •     
  • 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代码

    1. <servlet>    
    2.         servlet-name>HelloHessianservlet-name>    
    3.         servlet-class>    
    4.             com.caucho.hessian.server.HessianServlet     
    5.         servlet-class>    
    6.         init-param>    
    7.             param-name>home-classparam-name>    
    8.             param-value>michael.hessian.impl.HelloHessianImplparam-value>    
    9.         init-param>    
    10.         >home-api>michael.hessian.HelloHessianload-on-startup>1load-on-startup>    
    11.     servlet>    
    12.     servlet-mapping>    
    13.         servlet-name>    
    14.         url-pattern>/HessianServiceurl-pattern>    
    15.     servlet-mapping>    
    16.     >    

    3.java客户端验证

    package michael.hessian.client;     

  •     
  • import java.net.MalformedURLException;     
  • import michael.hessian.MyCar;     
  •     
  • import com.caucho.hessian.client.HessianProxyFactory;     
  •     
  •  *    
  • class HessianClientTest {     
  •     
  •          * @param args    
  • 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();     
  •         }     
  •     
  •     }     
  •     
  • }    
  • 运行结果如下:

  • welcom to Hessian     
  • my car name:[阿斯顿·马丁] model:[One-77].     
  • daughter   孙小美     
  • son   孙吴空     
  • apple     
  • kiwi     
  • orange   
  • 【二】、spring+hessian 实现服务端:

    1.基本代码见上面的demo

    2.修改配置文件

    在web.xml,增加内容如下:

    >springhessian>    

  •             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>  
  • 和上面的例子相似,只需要把访问的url替换成新的即可如下:

  • 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:

    import java.util.Map;     

  •     
  • import michael.hessian.HelloHessian;     
  • import michael.hessian.MyCar;     
  •     
  • import org.springframework.context.ApplicationContext;     
  • import org.springframework.context.support.ClasspathXmlApplicationContext;     
  •     
  • class HessianspringClient {     
  •     
  •     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 (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导入项目,一起运行正常,测试完全通过。

    版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

    相关推荐