-
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.javaJava代码
1. package michael.hessian;2. import java.util.List;3. import java.util.Map;4.5. /**6. * @author michael7. *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 michael7. *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 carName22. */23. public String getCarName() {24. return carName;25. }26.27. /**28. * @return the carModel29. */30. public String getCarModel() {31. return carModel;32. }33.34. /**35. * @param pCarName the carName to set36. */37. public void setCarName(String pCarName) {38. carName = pCarName;39. }40.41. /**42. * @param pCarModel the carModel to set43. */44. public void setCarModel(String pCarModel) {45. carModel = pCarModel;46. }47.48. /**49. * @see java.lang.Object#toString()50. * @return51. */52. @Override53. public String toString() {54. return "my car name:[" + this.carName + "] model:[" + this.carModel55. + "].";56. }57.58. }服务端接口的实现类:HelloHessianImpl.javaJava代码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 michael13. *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.基本代码见上面的demo2.修改配置文件在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.xmlXml代码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 exception3. 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)
相关文章: