Hessian是一个轻量级的remoting on http工具,采用的是Binary RPC协议,所以它很适合于发送二进制数据,同时又具有防火墙穿透能力。Hessian一般是通过Web应用来提供服务,因此非常类似于平时我们用的WebService。只是它不使用SOAP协议,但相比webservice而言更简单、快捷。
Hessian可通过Servlet提供远程服务,需要将匹配某个模式的请求映射到Hessian服务。也可Spring框架整合,通过它的DispatcherServlet可以完成该功能,DispatcherServlet可将匹配模式的请求转发到Hessian服务。Hessian的server端提供一个servlet基类, 用来处理发送的请求,而Hessian的这个远程过程调用,完全使用动态代理来实现的,,建议采用面向接口编程,Hessian服务通过接口暴露。
Hessian处理过程示意图:
客户端——>序列化写到输出流——>远程方法(服务器端)——>序列化写到输出流 ——>客户端读取输入流——>输出结果
下面详细介绍最常用的两种方式实现Hessian提供webservice:
1.纯Hessian实现
2.配合Spring框架实现
在开始之前当然需要到官网上下载相关的lib包,放入项目的/WEB-INF/lib/下
一、纯Hessian实现步骤:
1.编写hessianService类,也就是hessian接口
</pre><pre name="code" class="java">package com.taikang.hessian;
import java.util.List;
import java.util.Map;
public interface HelloHessian {
String sayHello();
MyCar getMyCar();
List<String> myLoveFruit();
Map<String, String> myBabays();
}
2.编写接口的实现类
package com.taikang.hessian;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.caucho.hessian.server.HessianServlet;
public class HelloHessianImpl extends HessianServlet implements HelloHessian {
public MyCar getMyCar() {
<span style="white-space:pre"> </span>MyCar car = new MyCar();
<span style="white-space:pre"> </span>car.setCarName("阿斯顿·马丁");
<span style="white-space:pre"> </span> car.setCarmodel("One-77");
<span style="white-space:pre"> </span>return car;
}
public Map<String, String> myBabays() {
<span style="white-space:pre"> </span> Map<String, String> map = new HashMap<String, String>();
<span style="white-space:pre"> </span>map.put("son", "孙吴空");
<span style="white-space:pre"> </span> map.put("daughter", "孙小美");
<span style="white-space:pre"> </span>return map;
}
public List<String> myLoveFruit() {
<span style="white-space:pre"> </span> List<String> list = new ArrayList<String>();
<span style="white-space:pre"> </span>list.add("apple");
<span style="white-space:pre"> </span>list.add("kiwi");
<span style="white-space:pre"> </span>list.add("orange");
<span style="white-space:pre"> </span> return list;
}
public String sayHello() {
<span style="white-space:pre"> </span>return "welcom to Hessian";
}
}
3.编写尸体类,用于传递数据,此类需序列化
package com.taikang.hessian;
import java.io.Serializable;
public class MyCar implements Serializable{
private static final long serialVersionUID = 4736905401908455439L;
private String carName;
private String carmodel;
public String getCarName() {
<span style="white-space:pre"> </span>return carName;
}
public String getCarmodel() {
<span style="white-space:pre"> </span>return carmodel;
}
public void setCarName(String pCarName) {
<span style="white-space:pre"> </span>carName = pCarName;
}
public void setCarmodel(String pCarmodel) {
<span style="white-space:pre"> </span>carmodel = pCarmodel;
}
public String toString() {
return "my car name:[" + this.carName + "] model:[" + this.carmodel
+ "].";
}
}
4.配置web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>hessian</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<span style="white-space:pre"> </span><servlet-name>HelloHessian</servlet-name>
<span style="white-space:pre"> </span><servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class> //hessian的jar包提供
<span style="white-space:pre"> </span><init-param>
<span style="white-space:pre"> </span><param-name>home-class</param-name>
<span style="white-space:pre"> </span><param-value>com.taikang.hessian.HelloHessianImpl</param-value> //hessian服务接口的实现类
<span style="white-space:pre"> </span></init-param>
<span style="white-space:pre"> </span><init-param>
<span style="white-space:pre"> </span><param-name>home-api</param-name>
<span style="white-space:pre"> </span><param-value>com.taikang.hessian.HelloHessian</param-value> //hessian服务接口
<span style="white-space:pre"> </span> <span style="white-space:pre"> </span></init-param>
<span style="white-space:pre"> </span><load-on-startup>1</load-on-startup>
<span style="white-space:pre"> </span></servlet>
<span style="white-space:pre"> </span><servlet-mapping>
<span style="white-space:pre"> </span> <span style="white-space:pre"> </span><servlet-name>HelloHessian</servlet-name>
<span style="white-space:pre"> </span> <span style="white-space:pre"> </span><url-pattern>/HessianService</url-pattern> //远程访问映射
<span style="white-space:pre"> </span> </servlet-mapping>
</web-app>
注意:以为是webservice,故该项目是一个web项目才可以想外提供服务,将该项目添加到tomcat服务器,启动准备被调用
5.编写客户端调用服务(需导入hessian的jar包)
package com.taikang.hessianClient;
import java.net.MalformedURLException;
import java.util.Map;
import com.caucho.hessian.client.HessianProxyFactory;
import com.taikang.hessian.HelloHessian;
import com.taikang.hessian.MyCar;
public class HessianClientTest {
public static void main(String[] args) {
String url = "http://localhost:8180/hessian/HessianService";//hessian服务的地址
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<String, String> 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();
}
}
}
6.执行结果
welcom to Hessian
my car name:[阿斯顿·马丁] model:[One-77].
daughter 孙小美
son 孙吴空
apple
kiwi
orange
二,spring+hessian 实现服务端
1.基本代码见上面的demo
2.修改配置文件, 在web.xml,增加内容如下:
<servlet>
<servlet-name>springhessian</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--
<init-param>
<span style="white-space:pre"> </span><param-name>contextConfigLocation</param-name>
<span style="white-space:pre"> </span><param-value>/WEB-INF/springhessian-servlet.xml</param-value>
</init-param>
-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<span style="white-space:pre"> </span><servlet-name>springhessian</servlet-name>
<span style="white-space:pre"> </span><url-pattern>/springhessian/*</url-pattern>
</servlet-mapping>
在/WEB-INF/增加一个叫servlet-name-servlet.xml配置文件。该文件的命名有一定的规则,红色 servlet-name 需要和web.xml中的<servlet-name>springhessian</servlet-name>定义的名称相匹配,比如本例子应叫springhessian-servlet.xml,这样简单也不容易出错。
当然该文件也可以自己任意命名。如果是自定义的文件名称不符合上述默认的规则,需要在<servlet>中增加<init-param>相关属性,人为指定加载配置文件,否则会报错。
范例:springhessian-servlet.xml
Xml代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "-beans.dtd">
<beans>
<span style="white-space:pre"> </span><bean id="helloHessianImpl" class="michael.hessian.impl.HelloHessianImpl" />
<span style="white-space:pre"> </span><!-- 使用HessianServiceExporter 将bean生成Hessian服务-->
<span style="white-space:pre"> </span><bean name="/helloHessianService" class="org.springframework.remoting.caucho.HessianServiceExporter">
<span style="white-space:pre"> </span><!-- 定义需要生成服务的实现类-->
<span style="white-space:pre"> </span><property name="service" ref="helloHessianImpl" />
<span style="white-space:pre"> </span><!-- Hessian 提供服务的接口-->
<span style="white-space:pre"> </span><property name="serviceInterface" value="michael.hessian.HelloHessian" />
<span style="white-space:pre"> </span></bean>
</beans>
3.java客户端验证
和上面的例子相似,只需要把访问的url替换成新的即可
4.spring配置客户端
增加一个spring的bean配置文件hessian-client.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "-beans.dtd">
<beans>
<span style="white-space:pre"> </span><bean id="helloHessianClient" class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
<span style="white-space:pre"> </span><property name="serviceUrl">
<span style="white-space:pre"> </span><value>
<span style="white-space:pre"> </span> //localhost:8082/J2EE_sjsky/springhessian/helloHessianService
<span style="white-space:pre"> </span></value>
<span style="white-space:pre"> </span> </property>
<span style="white-space:pre"> </span><property name="serviceInterface" value="michael.hessian.HelloHessian" />
<span style="white-space:pre"> </span> </bean>
</beans>
测试代码
package michael.hessian.client;
import java.util.Map;
import michael.hessian.HelloHessian;
import michael.hessian.MyCar;
import orgntext.ApplicationContext;
import orgntext.support.ClassPathXmlApplicationContext;
/**
* @author michael
*
*/
public class HessianSpringClient {
/**
* @param args
*/
public static 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 (Map.Entry<String, String> entry : hello.myBabays().entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
for (String str : hello.myLoveFruit()) {
System.out.println(str);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}