hessian是基于binary-RPC的通信库,通常是在某种传输协议上(如http)携带数据信息,通过网络来访问某台计算机的服务,有3使用方法我都尝试一下,首先都是服务端启动hessian服务,然后:
第1种:通过spring配置hessian的servlet
<bean name="/hessianHelloService" class="org.springframework.remoting.caucho.HessianServiceExporter"> <!-- 定义服务的实现类 --> <property name="service" ref="hessianHelloManager" /> <!-- 定义发布服务的接口 --> <property name="serviceInterface" value="com.hy.biz.manager.HelloManager" /> </bean>
String url = "http://127.0.0.1:8080/my-web/hessian/hessianHelloService";
HessianProxyFactory factory = new HessianProxyFactory();
HelloManager hessianHelloService = (HelloManager) factory.create(HelloManager.class, url);
第2种:通过spring将hessian客户端配置为普通的bean
<bean id="hessianHelloServiceClient" class="org.springframework.remoting.caucho.HessianProxyFactoryBean"> <property name="serviceUrl"> <value>http://localhost:8080/my-web/hessian/hessianHelloService</value> </property> <property name="serviceInterface"> <value>com.hy.biz.manager.HelloManager</value> </property> </bean>
HelloManager hi = (HelloManager)SpringBeanFactory.getBean("hessianHelloServiceClient");
第3种:将hessian配置为普通的servlet,调用方式和第1种一样
<servlet> <servlet-name>hessianHelloServlet</servlet-name> <servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class> <init-param> <param-name>home-class</param-name> <param-value>com.hy.biz.manager.impl.HessianHelloManager</param-value> </init-param> <init-param> <param-name>home-api</param-name> <param-value>com.hy.biz.manager.HelloManager</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>hessianHelloServlet</servlet-name> <url-pattern>/hello.h</url-pattern> </servlet-mapping>
hessian既然是http请求,能不通过浏览器直接访问呢?
看来不行,HessianServlet有如下代码:
那么用post请求hessian服务结果怎样呢?
==1
==2
==3
读取输入流的返回值是-1,说明输入流已经结束,或没有数据
通过程序请求hessian是ok的,那看看这2种请求方式有什么不同?
1)客户端header和浏览器header
POST /my-web/hello.h HTTP/1.1 Content-Type: x-application/hessian User-Agent: Java/1.7.0_21 Host: 127.0.0.1:8080 Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 Connection: keep-alive Content-Length: 22
POST /my-web/hello.h HTTP/1.1 Host: 127.0.0.1:8080 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:20.0) Gecko/20100101 Firefox/20.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive Pragma: no-cache Cache-Control: no-cache Content-Length: 0
2)content-type、ua、content-length等不同,前2项都好修改,那hessian post的内容是什么呢?
HessianProxy.java
AbstracthessianOutput.java
执行完call后,out对象的字节流如下:
[99, 2, 0, 109, 0, 8, 115, 97, 121, 72, 101, 108, 108, 111, 83, 0, 4, 109, 105, 107, 101, 122]
对应的字符是:c20m08sayHelloS04mikez,但直接在post里面写上却报异常:方法找不到
明显是没有将方法参数和方法区分开,难道hessian还在哪里有做列特殊标记的吗?
再次debug,发现m后面的0和8读取出来的是ascii码48和56,这些是不对的,应该读取出来的是ascii码里的0和8,分别是控制字符NUT和BS,那怎么用键盘输出这2个控制字符呢?
ASCII 字符集,最基本的包含了 128 个字符。其中前 32 个, 0-31 ,即 0x00-0x1F ,都是不可见字符。这些字符,就叫做控制字符。这些字符没法打印出来,但是每个字符,都对应着一个特殊的控制功能的字符,简称功能字符或功能码 Function Code 。 简言之: ASCII 中前 32 个字符,统称为 Function Code 功能字符。此外,由于 ASCII 中的 127 对应的是 Delete ,也是不可见的,所以,此处根据笔者的理解,也可以归为 Function Code 。
---------------------------------------------------------------------------------------------------------
其它:
1)Hessian的学习笔记,http://wenku.baidu.com/view/4c29750202020740be1e9b0b.html
2)hessian调用只支持post方法, http://sd-zyl.iteye.com/blog/1768928
3)Hessian源码分析和Hack --让Hessian携带远程调用端的信息,http://dev.21tx.com/2009/01/16/13489.html
4)The Hessian Protocol,http://blog.sina.com.cn/s/blog_4836510801000aj4.html
5)http://fancyboy2050.iteye.com/blog/1717680
6)ascii码,http://www.360doc.com/content/11/1208/05/1258863_170546100.shtml
7)ascii码控制字符, http://blog.chinaunix.net/uid-23802873-id-3307585.html