一、介绍
Hessian 是工作在 HTTP 协议上的远程调用框架:请求信息被序列化为二进制数据通过 HTTP 请求传输到服务器端,服务端查找目标方法,用请求参数进行调用,然后把响应结果序列化为二进制数据,作为 HTTP 响应返回给客户端,客户端再解析数据组成应用所使用的 Java 对象。
二、服务接口
首先要定义一个 Java 接口来表示远程服务:
public interface IHessianService {
User getUser();
User createUser(String name, int age, char sex);
Map<String, Object> getMap();
String getString(String value);
int getInt(int i);
}
定义多个方法是为了测试下不同的数据类型的支持度。User
是个自定义的类型,必须实现 java.io.Serializable
。
服务端暴露这个接口来表示可以被调用的服务,客户端使用这个接口来表示可以调用的远程服务。
三、服务器端实现
服务器端要实现上面的服务接口,然后配置暴露这个服务。
public class MyHessianService implements IHessianService {
private Logger logger = LoggerFactory.getLogger(MyHessianService.class);
@Override
public User getUser() {
return createUser("cb 4 hessian test .", 29, 'Y');
}
@Override
public User createUser(String name, int age, char sex) {
User user = new User();
user.setAge(age);
user.setName(name);
user.setSex(sex);
logger.info("create user, name:" + name + ", age:" + age + ", sex:"
+ sex);
return user;
}
@Override
public Map<String, Object> getMap() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("map_key", "map_value");
map.put("map_key1", "map_value1");
map.put("map_key2", "map_value2");
return map;
}
@Override
public String getString(String value) {
return value;
}
@Override
public int getInt(int i) {
return i;
}
}
配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
<!-- 定义服务的实现 bean -->
<bean id="hessianService" class="net.coderbee.demo.service.hessian.MyHessianService" />
<!-- 配置暴露的服务,bean name 以 / 开头的 Spring 会自动进行 url 映射 -->
<bean name="/hessianService" lass="org.springframework.remoting.caucho.HessianServiceExporter">
<property name="service" ref="hessianService" />
<property name="serviceInterface" value="net.coderbee.demo.service.hessian.IHessianService" />
</bean>
</beans>
这样,客户端就可以通过 url http://host:port/application-context/hessianService
来调用这个服务。
四、客户端端调用
客户端首先要配置对远程服务的代理:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="hessianService" class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
<property name="serviceUrl" value="http://localhost:8080/ssm3/hessianService" />
<property name="serviceInterface" value="net.coderbee.demo.service.hessian.IHessianService" />
</bean>
</beans>
把上面的配置保存在类路径下的: test-hessian.xml
。
调用代码示例:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/test-hessian.xml")
public class TestHessianService {
@Autowired
private IHessianService hessianService;
private Logger logger = LoggerFactory.getLogger(TestHessianService.class);
@Test
public void test() {
User user = hessianService.getUser();
logger.info("name:{}, age:{}", user.getName(), user.getAge());
User user2 = hessianService.createUser("pass primitive data", 30, 'B');
logger.info("name:{}, age:{}", user2.getName(), user2.getAge());
Map<String, Object> map = hessianService.getMap();
logger.info("test get map : {}", map);
String string = hessianService.getString("test string value");
logger.info(string);
int i = hessianService.getInt(123);
logger.info("test get int : {}", i);
}
}
客户端执行 hessianService.getInt(123)
的调用时服务端输出如下:
16:23:38.661 [http-apr-8080-exec-1] DEBUG o.s.web.servlet.DispatcherServlet - DispatcherServlet with name 'spring' processing POST request for [/ssm3/hessianService]
16:23:38.661 [http-apr-8080-exec-1] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Looking up handler method for path /hessianService
16:23:38.671 [http-apr-8080-exec-1] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Did not find handler method for [/hessianService]
16:23:38.671 [http-apr-8080-exec-1] DEBUG o.s.w.s.h.BeanNameUrlHandlerMapping -Mapping [/hessianService] to HandlerExecutionChain with handler org.springframework.remoting.caucho.HessianServiceExporter@3da02a95] and 1 interceptor
16:23:38.671 [http-apr-8080-exec-1] DEBUG o.s.r.s.RemoteInvocationTraceInterceptor - Incoming HessianServiceExporter remote call: net.coderbee.demo.service.hessian.IHessianService.getInt
16:23:38.671 [http-apr-8080-exec-1] DEBUG o.s.r.s.RemoteInvocationTraceInterceptor - Finished processing of HessianServiceExporter remote call: net.coderbee.demo.service.hessian.IHessianService.getInt
16:23:38.671 [http-apr-8080-exec-1] DEBUG o.s.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'spring': assuming HandlerAdapter completed request handling
16:23:38.671 [http-apr-8080-exec-1] DEBUG o.s.web.servlet.DispatcherServlet - Successfully completed request
从整个过程来看,Hessian 的使用还是很简单的。
欢迎关注我的微信公众号: coderbee笔记,可以更及时回复你的讨论。
博主这个有没有完整源码~我是一个php程序员对java不太熟悉,但是目前需要使用hessian能够使java和php通信,所以想借用你的例子,学习一下谢谢~
我这个例子是 Spring 集成 Hessian,好处就是业务代码完全与 Hessian 无关,不需要关注那些序列化之类的问题,Hessian 有关的只有配置。你如果需要在 java和php之间用Hessian,其实是使用Hessian的序列化协议,这个可以去官网上找找。