zoukankan      html  css  js  c++  java
  • 利用Hessian如何实现Webservice

    利用Hessian如何实现Webservice

    [] [] [] 发布人:圣才学习网  发布日期:2012-08-18 14:02  共966人浏览
    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<STRING,&NBSP;STRING> myBabays();     
    18.           
    19.       }   
    一个java bean文件MyCar.java:
    Java代码
    1.           package michael.hessian;     
    2.               
    3.           import java.io.Serializable;     
    4.               
    5.           /**    
    6.            * @author michael    
    7.            *     
    8.            */    
    9.           public class MyCar implements Serializable {     
    10.           
    11.           /**    
    12.            *     
    13.            */    
    14.           private static final long serialVersionUID = 4736905401908455439L;     
    15.           
    16.           private String carName;     
    17.           
    18.           private String carModel;     
    19.           
    20.           /**    
    21.            * @return the carName    
    22.            */    
    23.           public String getCarName() {     
    24.               return carName;     
    25.           }     
    26.           
    27.           /**    
    28.            * @return the carModel    
    29.            */    
    30.           public String getCarModel() {     
    31.               return carModel;     
    32.           }     
    33.           
    34.           /**    
    35.            * @param pCarName the carName to set    
    36.            */    
    37.           public void setCarName(String pCarName) {     
    38.               carName = pCarName;     
    39.           }     
    40.           
    41.           /**    
    42.            * @param pCarModel the carModel to set    
    43.            */    
    44.           public void setCarModel(String pCarModel) {     
    45.               carModel = pCarModel;     
    46.           }     
    47.           
    48.           /**    
    49.            * @see java.lang.Object#toString()    
    50.            * @return    
    51.            */    
    52.           @Override    
    53.           public String toString() {     
    54.               return "my car name:[" + this.carName + "] model:[" + this.carModel     
    55.                       + "].";     
    56.           }     
    57.           
    58.       }   
    服务端接口的实现类:HelloHessianImpl.java
    Java代码
    1.           package michael.hessian.impl;     
    2.               
    3.           import java.util.ArrayList;     
    4.           import java.util.HashMap;     
    5.           import java.util.List;     
    6.           import java.util.Map;     
    7.               
    8.           import michael.hessian.HelloHessian;     
    9.           import michael.hessian.MyCar;     
    10.           
    11.       /**    
    12.        * @author michael    
    13.        *     
    14.        */    
    15.       public class HelloHessianImpl extends HessianServlet implements HelloHessian {     
    16.           
    17.           public MyCar getMyCar() {     
    18.               MyCar car = new MyCar();     
    19.               car.setCarName("阿斯顿·马丁");     
    20.               car.setCarModel("One-77");     
    21.               return car;     
    22.           }     
    23.           
    24.           public Map<STRING,&NBSP;STRING> myBabays() {     
    25.               Map<STRING,&NBSP;STRING> map = new HashMap<STRING,&NBSP;STRING>();     
    26.               map.put("son""孙吴空");     
    27.               map.put("daughter""孙小美");     
    28.               return map;     
    29.           }     
    30.           
    31.           public List myLoveFruit() {     
    32.               List list = new ArrayList();     
    33.               list.add("apple");     
    34.               list.add("kiwi");     
    35.               list.add("orange");     
    36.               return list;     
    37.           }     
    38.           
    39.           public String sayHello() {     
    40.               return "welcom to Hessian";     
    41.           }     
    42.           
    43.       }   
    2.配置文件web.xml修改
    在web.xml配置文件里增加如下信息:
    Xml代码
    1.           <servlet>    
    2.                   <servlet-name>HelloHessian</< span>servlet-name>    
    3.                   <servlet-class>    
    4.                       com.caucho.hessian.server.HessianServlet     
    5.                   </< span>servlet-class>    
    6.                   <init-param>    
    7.                       <param-name>home-class</< span>param-name>    
    8.                       <param-value>michael.hessian.impl.HelloHessianImpl</< span>param-value>    
    9.                   </< span>init-param>    
    10.               <init-param>    
    11.                   <param-name>home-api</< span>param-name>    
    12.                   <param-value>michael.hessian.HelloHessian</< span>param-value>    
    13.               </< span>init-param>    
    14.               <load-on-startup>1</< span>load-on-startup>    
    15.           </< span>servlet>    
    16.           <servlet-mapping>    
    17.               <servlet-name>HelloHessian</< span>servlet-name>    
    18.               <url-pattern>/HessianService</< span>url-pattern>    
    19.           </< span>servlet-mapping>    
    20.           <servlet-mapping>    
    3.java客户端验证
    Java代码
    1.           package michael.hessian.client;     
    2.               
    3.           import java.net.MalformedURLException;     
    4.           import java.util.Map;     
    5.               
    6.           import michael.hessian.HelloHessian;     
    7.           import michael.hessian.MyCar;     
    8.               
    9.           import com.caucho.hessian.client.HessianProxyFactory;     
    10.           
    11.       /**    
    12.        * @author michael    
    13.        *    
    14.        */    
    15.       public class HessianClientTest {     
    16.           
    17.           /**    
    18.            * @param args    
    19.            */    
    20.           public static void main(String[] args) {     
    21.               String url = "http://localhost:8082/J2EE_sjsky/HessianService";     
    22.               HessianProxyFactory factory = new HessianProxyFactory();     
    23.               try {     
    24.                   HelloHessian hello = (HelloHessian) factory.create(     
    25.                           HelloHessian.class, url);     
    26.                   System.out.println(hello.sayHello());     
    27.           
    28.                   MyCar car = hello.getMyCar();     
    29.                   System.out.println(car.toString());     
    30.           
    31.                   for (Map.Entry<STRING,&NBSP;STRING> entry : hello.myBabays().entrySet()) {     
    32.                       System.out.println(entry.getKey() + "   " + entry.getValue());     
    33.                   }     
    34.           
    35.                   for (String str : hello.myLoveFruit()) {     
    36.                       System.out.println(str);     
    37.                   }     
    38.           
    39.               } catch (MalformedURLException e) {     
    40.                   e.printStackTrace();     
    41.               }     
    42.           
    43.           }     
    44.           
    45.       }    
    运行结果如下:
    Java代码
    1.           welcom to Hessian     
    2.           my car name:[阿斯顿·马丁] model:[One-77].     
    3.           daughter   孙小美     
    4.           son   孙吴空     
    5.           apple     
    6.           kiwi     
    7.           orange   
    【二】、spring+hessian 实现服务端:
    1.基本代码见上面的demo
    2.修改配置文件
    在web.xml,增加内容如下:
    Xml代码
    1.           <servlet>    
    2.                   <servlet-name>springhessian</< span>servlet-name>    
    3.                   <servlet-class>    
    4.                       org.springframework.web.servlet.DispatcherServlet     
    5.                   </< span>servlet-class>    
    6.                       
    7.               <bean name="/helloHessianService"    
    8.                   class="org.springframework.remoting.caucho.HessianServiceExporter">    
    9.                       
    10.               <property name="service" ref="helloHessianImpl" />    
    11.                   
    12.               <property name="serviceInterface"    
    13.                   value="michael.hessian.HelloHessian" />    
    14.           </< span>bean>    
    15.       </< span>beans>  
    3.java客户端验证
    和上面的例子相似,只需要把访问的url替换成新的即可如下:
    Java代码
    1.           String url=http://localhost:8082/J2EE_sjsky/springhessian/helloHessianService   
    运行结果和上面例子一样。
    4.spring配置客户端
    增加一个spring的bean配置文件hessian-client.xml
    Xml代码
    1.           <?xml version="1.0" encoding="UTF-8"?>    
    2.           >    
    3.           <beans>    
    4.               <bean id="helloHessianClient"    
    5.                   class="org.springframework.remoting.caucho.HessianProxyFactoryBean">    
    6.                   <property name="serviceUrl">    
    7.                       <value>    
    8.                           http://localhost:8082/J2EE_sjsky/springhessian/helloHessianService     
    9.                       </< span>value>    
    10.               </< span>property>    
    11.               <property name="serviceInterface"    
    12.                   value="michael.hessian.HelloHessian" />    
    13.           </< span>bean>    
    14.       </< span>beans>    
    测试代码HessianSpringClient.java:
    Java代码
    1.           package michael.hessian.client;     
    2.               
    3.           import java.util.Map;     
    4.               
    5.           import michael.hessian.HelloHessian;     
    6.           import michael.hessian.MyCar;     
    7.               
    8.           import org.springframework.context.ApplicationContext;     
    9.           import org.springframework.context.support.ClassPathXmlApplicationContext;     
    10.           
    11.       /**    
    12.        * @author michael    
    13.        *     
    14.        */    
    15.       public class HessianSpringClient {     
    16.           
    17.           /**    
    18.            * @param args    
    19.            */    
    20.           public static void main(String[] args) {     
    21.               try {     
    22.                   ApplicationContext context = new ClassPathXmlApplicationContext(     
    23.                           "hessian-client.xml");     
    24.           
    25.                   HelloHessian hello = (HelloHessian) context     
    26.                           .getBean("helloHessianClient");     
    27.           
    28.                   System.out.println(hello.sayHello());     
    29.           
    30.                   MyCar car = hello.getMyCar();     
    31.                   System.out.println(car.toString());     
    32.           
    33.                   for (Map.Entry<STRING,&NBSP;STRING> entry : hello.myBabays().entrySet()) {     
    34.                       System.out.println(entry.getKey() + "   " + entry.getValue());     
    35.                   }     
    36.           
    37.                   for (String str : hello.myLoveFruit()) {     
    38.                       System.out.println(str);     
    39.                   }     
    40.               } catch (Exception e) {     
    41.                   e.printStackTrace();     
    42.               }     
    43.           
    44.           }     
    45.           
    46.       }   
    运行结果和上面完全一致。
    5.com.caucho.hessian.io.HessianProtocolException: expected string at 0x6d异常处理
    我在spring+hessian整合测试过程中,客户端调用时,发生了异常,而服务端错误内容如下:
    Java代码
    1.           2011-4-25 16:14:44 org.apache.catalina.core.StandardWrapperValve invoke     
    2.           严重: Servlet.service() for servlet remoting threw exception     
    3.           com.caucho.hessian.io.HessianProtocolException: expected string at 0x6d    
    4.               at com.caucho.hessian.io.Hessian2Input.error(Hessian2Input.java:2882)     
    5.               at com.caucho.hessian.io.Hessian2Input.expect(Hessian2Input.java:2830)     
    6.               at com.caucho.hessian.io.Hessian2Input.readString(Hessian2Input.java:1362)     
    7.               at com.caucho.hessian.io.Hessian2Input.readMethod(Hessian2Input.java:272)     
    8.               at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:249)     
    9.               at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:221)     
    10.           at org.springframework.remoting.caucho.Hessian2SkeletonInvoker.invoke(Hessian2SkeletonInvoker.java:67)     
    11.           at org.springframework.remoting.caucho.HessianServiceExporter.handleRequest(HessianServiceExporter.java:147)     
    12.           at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:49)     
    13.           at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:819)     
    14.           at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:754)     
    15.           at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:399)     
    16.           at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:364)     
    17.           at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)     
    18.           at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)     
    19.           at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)     
    20.           at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)     
    21.           at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)     
    22.           at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)     
    23.           at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)     
    24.           at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)     
    25.           at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)     
    26.           at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:261)     
    27.           at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)     
    28.           at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:581)     
    29.           at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)     
    30.           at java.lang.Thread.run(Thread.java:619)   
     
  • 相关阅读:
    【BZOJ4890】[TJOI2017]城市(动态规划)
    【BZOJ4887】[TJOI2017]可乐(矩阵快速幂)
    【BZOJ4873】[六省联考2017]寿司餐厅(网络流)
    【BZOJ4868】[六省联考2017]期末考试(贪心)
    【Luogu3733】[HAOI2017]八纵八横(线性基,线段树分治)
    【Luogu3732】[HAOI2017]供给侧改革(Trie树)
    【Luogu3731】[HAOI2017]新型城市化(网络流,Tarjan)
    【BZOJ5332】[SDOI2018]旧试题(数论,三元环计数)
    28人买可乐喝,3个可乐瓶盖可以换一瓶可乐,那么要买多少瓶可乐,够28人喝?假如是50人,又需要买多少瓶可乐?
    基础学习day07---面向对象三---继承,接口与 抽象类
  • 原文地址:https://www.cnblogs.com/firstdream/p/4820572.html
Copyright © 2011-2022 走看看