Spring Hessian 集成

一、介绍

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笔记,可以更及时回复你的讨论。

Spring Hessian 集成》上有2个想法

  1. 博主这个有没有完整源码~我是一个php程序员对java不太熟悉,但是目前需要使用hessian能够使java和php通信,所以想借用你的例子,学习一下谢谢~

    • 我这个例子是 Spring 集成 Hessian,好处就是业务代码完全与 Hessian 无关,不需要关注那些序列化之类的问题,Hessian 有关的只有配置。你如果需要在 java和php之间用Hessian,其实是使用Hessian的序列化协议,这个可以去官网上找找。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据