Hessian是一个轻量级的远程调用工具,采用的是Binary RPC协议,很适合于发送二进制数据,基于HTTP具有防火墙穿透能力。Hessian一般是通过Web应用来提供服务,因此非常类似于平时我们用的Web Service。只是它不使用SOAP协议,但相比Web Service而言更简单、快捷。
Burlap与Hessian相似,只是Burlap传输的将是XML而不是二进制的数据。
RMI很难穿越防火墙,2端都必须基于Java开发,传输对象时还需要考虑对象版本的问题。而Burlap与Hessian是基于HTTP的,很容易穿越防火墙,而且客户端不仅限于Java。Burlap与Hessian用的是私有的对象序列化机制,比起RMI来效率是较低的,RMI用的是Java的序列化机制。
Spring还提供了一种RPC机制—HTTP invoker,基于HTTP传输,使用的又是Java的对象序列化机制。
1. Hessian框架JAR包下载
从http://hessian.caucho.com/上下载所需的JAR包,这里下载的是hessian-4.0.37.jar。hessian的jar包是非常的小。
特别需要注意的是:hessian-4.0.37.jar不仅要放到工程依赖的jar包中,还要放在web-inf下的lib目录下,否则会报错:
NoClassDefFoundError: com/caucho/hessian/io/HessianDebugInputStream
2.服务器端环境搭建
2.1和RMI一样,需要先定义一个接口:
package com.hessian.isay; public interface Isay { public String sayHello(String arg1,String arg2); public String getObjectMessage(Object object); }
2.2再编写一个具体的实现类:
package com.hessian.isay; public class IsayImpl implements Isay { public String sayHello(String arg1, String arg2) { return "Hello:" + arg1 + arg2; } @Override public String getObjectMessage(Object object) { if(object instanceof HessianTestObject){ return "server react :" + ((HessianTestObject) object).getMessage(); } return ""; }}
2.3 创建一个对象,证明可以传输对象
package com.hessian.isay; import java.io.Serializable; public class HessianTestObject implements Serializable{ private static final long serialVersionUID = -6273473338054054934L; private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
2.4配置web.xml,加上下面的代码:
<servlet> <description>spring mvc servlet</description> <servlet-name>springMvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet </servlet-class> <init-param> <description>spring mvc 配置文件</description> <param-name>contextConfigLocation</param-name> <param-value> classpath:springMvc-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springMvc</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
这里需要注意的是,DispatcherServlet的servlet-name是springMvc,所以需要新建一个名为springMvc-servlet.xml的文件。tomcat在启动时将会去加载这个文件。
2.5 创建springMvc-servlet.xml文件
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!-- 接口的具体实现类 --> <bean id="impl" class="com.hessian.isay.IsayImpl" /> <!-- 使用Spring的HessianService做代理 --> <bean name="/helloSpring.do" class="org.springframework.remoting.caucho.HessianServiceExporter"> <!-- service引用具体的实现实体Bean--> <property name="service" ref="impl" /> <property name="serviceInterface" value="com.hessian.isay.Isay" /> </bean> <!-- 可以配置多个HessianServiceExporter代理Bean --> </beans>
启动tomcat服务器,如果没报异常,则说明服务器端的环境搭建完成了。
3.客户端环境搭建
客户端需要的是hessian-4.0.37.jar,HessianTestObject,Isay和NormalClient(或者SpringClient)。
3.1 不依赖于Spring的方式调用
编写测试类如下:
import java.net.MalformedURLException; import com.caucho.hessian.client.HessianProxyFactory; import com.hessian.isay.Isay; public class NormalClient { public static void main(String[] args) throws MalformedURLException { //Spring Hessian代理Servelet String url = "http://localhost:8080/ssm/helloSpring.do"; HessianProxyFactory factory = new HessianProxyFactory(); Isay api = (Isay) factory.create(Isay.class, url); System.out.println(api.sayHello("hello", " spring")); HessianTestObject object = new HessianTestObject(); object.setMessage("message from object"); System.out.println(api.getObjectMessage(object)); } }
3.2 依赖于Spring的实现
先编写xml文件hessian_client.xml,完成bean的定义:
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!-- 客户端Hessian代理工厂Bean --> <bean id="clientSpring" class="org.springframework.remoting.caucho.HessianProxyFactoryBean"> <!-- 请求代理Servlet路径 --> <property name="serviceUrl"> <value>http://localhost:8080/ssm/helloSpring.do</value> </property> <!-- 接口定义 --> <property name="serviceInterface"> <value>com.hessian.isay.Isay</value> </property> </bean> </beans>
上面直接写死url的方式不是很好,写成如下方式更为灵活:http://${serverName}:${httpPort}/${serverPath}/${contextPath}。
再编写测试代码,如下:
package com.hessian.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.hessian.isay.Isay; public class SpringClient { public static void main(String[] args) { ApplicationContext contex = new ClassPathXmlApplicationContext( "hessian_client.xml"); // 获得客户端的Hessian代理工厂bean Isay i = (Isay) contex.getBean("clientSpring"); System.out.println(i.sayHello("hello", " spring")); HessianTestObject object = new HessianTestObject(); object.setMessage("message from object"); System.out.println(i.getObjectMessage(object)); } }
Burlap的环境搭建与Hessian很类似,需要的也是hessian-4.0.37.jar。
需要有2处需要更改:
一是将步骤2.5中的配置文件配置如下即可:
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!-- 接口的具体实现类 --> <bean id="impl" class="com.hessian.isay.IsayImpl" /> <!-- 使用Spring的HessianService做代理 ,service引用具体的实现实体Bean--> <!-- <bean name="/helloSpring.do" class="org.springframework.remoting.caucho.HessianServiceExporter"> <property name="service" ref="impl" /> <property name="serviceInterface" value="com.hessian.isay.Isay" /> </bean> --> <bean name="/helloSpring.do" class="org.springframework.remoting.caucho.BurlapServiceExporter"> <property name="service" ref="impl" /> <property name="serviceInterface" value="com.hessian.isay.Isay" /> </bean> <!-- 可以配置多个HessianServiceExporter代理Bean --> </beans>
二是将3.2中的配置文件改为:
<bean id="clientSpring" class="org.springframework.remoting.caucho.BurlapProxyFactoryBean"> <!-- 请求代理Servlet路径 --> <property name="serviceUrl"> <value>http://localhost:8080/ssm/helloSpring.do</value> </property> <!-- 接口定义 --> <property name="serviceInterface"> <value>com.hessian.isay.Isay</value> </property> </bean>
Spring自带的HttpInvoker基于Http,而且使用Java自带的序列化。配置和Hessian基本的一样,也只需要该2处地方。
使用HttpInvoker的缺点是必须使用Spring和必须基于Java。
一是将步骤2.5中的配置文件配置如下即可:
<bean name="/helloSpring.do" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter"> <property name="service" ref="impl" /> <property name="serviceInterface" value="com.hessian.isay.Isay" /> </bean>
二是将3.2中的配置文件改为:
<bean id="clientSpring" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean"> <property name="serviceUrl"> <value>http://localhost:8080/ssm/helloSpring.do</value> </property> <property name="serviceInterface"> <value>com.hessian.isay.Isay</value> </property> </bean>