Spring整合Hessian

转载自 Spring整合Hessian

前言:

      近日着手研究了一下Hessian的rmi方案,因为客户端是多种移动终端平台,本来想采用传说中的phprpc(hprose?)的,但看了下官方的文档,发现没有object-c的版本,故而放弃。

      跟着hessian 的官方例子走,跑起来是没有问题的,但我在试着跟spring整合的时候,出了不少的问题。记录一下,方便自己以及路人,呵呵。

 

环境说明:

 

  • spring        version 3.0      RELEASE.
  • Hessian      version  4.0.7  WHATEVER.
  • JEE            version 2.5

实现步骤:

  1. 配置 web.xml ,添加对spring-web中 DispatcherServlet的定义.具体如下:
    Xml代码   收藏代码
    1. <servlet>  
    2.         <servlet-name>test-remote</servlet-name>  
    3.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
    4.         <init-param>  
    5.             <param-name>contextConfigLocation</param-name>  
    6.             <param-value>/WEB-INF/config/test-remote.xml</param-value>  
    7.         </init-param>  
    8.         <load-on-startup>4</load-on-startup>  
    9. </servlet>  
    10.   
    11. <servlet-mapping>  
    12.         <servlet-name>test-remote</servlet-name>  
    13.         <url-pattern>/remote/*</url-pattern>  
    14. </servlet-mapping>  
     Tips:
        A.  很多网友都说一定要在WEB-INF下面放入跟servlet-name相对应的 test-remote-servlet.xml 配置文件,实际上是不一定要那么处理的。如果指定了 contextConfigLocation的话,就可以解决这个问题。意味着spring不会强制要求你配置文件的位置。
        B.  DispatcherServlet是可以配置多个的,我这里还有一个test-local,mapping着 "/" 路径,他们之间并不会影响。当然可以单纯的配置多个 servlet-mapping.我只是想验证一下,结果说明确实是可以的。    
  2.  传输对象类Space 的定义:
    Java代码   收藏代码
    1. package test.remote.dto;  
    2.   
    3. import java.io.Serializable;  
    4. import java.util.Date;  
    5.   
    6. /** 
    7.  * Space data transfer object. 
    8.  * @author gogo 
    9.  *  
    10.  */  
    11. public class Space implements Serializable{  
    12.       
    13.   /** 
    14.      * auto generated serialVersionUid. 
    15.      */  
    16.     private static final long serialVersionUID = 5632812127919571530L;    
    17.       
    18.     /** public space name for people in the space.*/  
    19.     private String publicName;  
    20.     private String privateName;  
    21.     private boolean isActive;  
    22.     private Date lastUpdatedTime;  
    23.   
    24.     /** 
    25.          *  setter & getter 
    26.          */  
    27.       
    28.     @Override  
    29.     public String toString() {  
    30.         StringBuilder buffer = new StringBuilder("Space:");  
    31.         buffer.append("public name:").append(publicName).append(", ");  
    32.         buffer.append("private name:").append(privateName).append(", ");  
    33.         buffer.append("is actived:").append(isActive).append(", ");  
    34.         buffer.append("lastUpdatedTime:").append(lastUpdatedTime.getTime());  
    35.         return buffer.toString();  
    36.     }   
    37. }  
     
  3.   服务接口的定义如下:
       package test.remote.service;
    Java代码   收藏代码
    1. import java.util.List;  
    2.   
    3. import test.remote.dto.Space;  
    4.   
    5. /** 
    6.  *  
    7.  * @author gogo 
    8.  * 
    9.  */  
    10. public interface SpaceService {  
    11.       
    12.     List showSpaceNames(); //返回名字集合  
    13.       
    14.     Space findSpace(String id);//找到空间名字  
    15.       
    16.     boolean updateSpaceName(String name); //更新空间名字  
    17.       
    18. }  
     
  4. 服务接口实现类:
      package test.remote.service.impl;
    Java代码   收藏代码
    1. import java.util.ArrayList;  
    2. import java.util.Date;  
    3. import java.util.List;  
    4.   
    5. import org.apache.commons.logging.Log;  
    6. import org.apache.commons.logging.LogFactory;  
    7. import org.springframework.remoting.caucho.HessianServiceExporter;  
    8.   
    9. import test.remote.dto.Space;  
    10. import test.remote.service.SpaceService;  
    11.   
    12. /** 
    13.  * 这个是一个远程接口的测试实现<br> 
    14.  * 该接口会由spring的 {@link HessianServiceExporter}以Http服务的形式暴露.<br> 
    15.  * 客户端会依赖Hessian实现 
    16.  * @see HessianServiceExporter 
    17.  * @author gogo  
    18.  *  
    19.  */  
    20. public class SpaceServiceImpl implements SpaceService{  
    21.       
    22.     private static final Log log = LogFactory.getLog(SpaceServiceImpl.class);  
    23.       
    24.     private Space createSpace() {  
    25.         Space space = new Space();  
    26.         space.setPublicName("roosher-space");  
    27.         space.setPrivateName("my-private-room");  
    28.         space.setActive(true);  
    29.         space.setLastUpdatedTime(new Date());  
    30.         return space;  
    31.     }  
    32.   
    33.     public Space findSpace(String id) {  
    34.         // TODO Auto-generated method stub  
    35.         log.debug("find space id is :" + id);  
    36.         return createSpace();  
    37.     }  
    38.   
    39.     public List showSpaceNames() {  
    40.         // TODO Auto-generated method stub  
    41.         List names = new ArrayList<String>();  
    42.         for (int i = 0; i < 10; i++) {  
    43.             names.add("Hello space "+ i);  
    44.         }  
    45.         return names;  
    46.     }  
    47.   
    48.     public boolean updateSpaceName(String name) {  
    49.         // TODO Auto-generated method stub  
    50.         log.debug("updated space name : " + name );  
    51.         return true;  
    52.     }  
    53.       
    54. }  
     
  5.  test-remote.xml的内容:
    Xml代码   收藏代码
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <beans xmlns="http://www.springframework.org/schema/beans"  
    3.     xmlns:context="http://www.springframework.org/schema/context"  
    4.         xmlns:p="http://www.springframework.org/schema/p"  
    5.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    6.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
    7.         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
    8.     http://www.springframework.org/schema/context  
    9.         http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
    10.     <bean   
    11.         class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"  
    12.                          p:order="1"></bean>  
    13.           
    14.     <bean id="spaceService" class="test.service.impl.SpaceServiceImpl">  
    15.         </bean>  
    16.       
    17.     <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter">  
    18.         </bean>  
    19.   
    20.     <bean name="/SpaceHessian"   
    21.         class="org.springframework.remoting.caucho.HessianServiceExporter"  
    22.         p:serviceInterface="test.remote.service.SpaceService"  
    23.         p:service-ref="spaceService">  
    24.     </bean>  
    25.       
    26.     <bean name="/SpaceBurlap"  
    27.              class="org.springframework.remoting.caucho.BurlapServiceExporter"  
    28.              p:serviceInterface="test.remote.service.SpaceService"  
    29.              p:service-ref="spaceService">  
    30.         </bean>  
    31.       
    32. </beans>  
     Tips:
         A.  BeanNameUrlHandlerMapping 属性中的 p:order="1",可以不用配置.避免跟自己的冲突.    
         B.  HttpRequestHandlerAdapter 在这里面非常关键,没有它可能会出现这种错误:
            -- No adapter for handler Does your handler implement a supported interface like Controller ?                 HttpRequestHandlerAdapter它的作用就是让spring-mvc放出权限给下面的Exporter自己处理整个HTTP 流程.毕竟HessianServiceExporter也是实现的HttpRequestHandler
  6. 客户端的两种实现:
    A.  就是基于spring的实现,采用org.springframework.remoting.caucho.HessianProxyFactoryBean实现,相关配置如下:
         
    Java代码   收藏代码
    1. <bean id="spaceServiceHessian"  
    2.         class="org.springframework.remoting.caucho.HessianProxyFactoryBean">  
    3.     <property name="serviceUrl"  
    4.           value="http://localhost:8080/test/remote/SpaceHessian" />  
    5.     <property name="serviceInterface" value="test.remote.service.SpaceService" />  
    6. </bean>  
    7.   
    8. <bean id="spaceServiceBurlap"  
    9.         class="org.springframework.remoting.caucho.BurlapProxyFactoryBean">  
    10.         <property name="serviceUrl"  
    11.                   value="http://localhost:8080/test/remote/SpaceBurlap" />  
    12.         <property name="serviceInterface" value="test.remote.service.SpaceService" />  
    13. </bean>  
     注意到里面的URL了没? 其中 http://localhost:8080/test/remote/SpaceHessian 的/SpaceHessian 对应的是之前在remote-test.xml中配置的<bean name="/SpaceHessian"> </bean>的URI.

    然后通过spring获取上下文之后,就可以直接注入 SpaceService service = context.getBean("spaceServiceBurlap");

    B . 就是基于Hessian 自己提供的客户端,这里展示的是Java版本.
      
  7. Java代码   收藏代码
    1. package test.remote;  
    2.   
    3. import java.net.MalformedURLException;  
    4. import java.util.List;  
    5.   
    6. import com.caucho.hessian.client.HessianProxyFactory;  
    7. import test.remote.dto.Space;  
    8. import test.remote.service.SpaceService;  
    9.   
    10. /** 
    11.  * 连接客户端。测试时要注意 url的ip地址. 
    12.  * @see Space 
    13.  * @author gogo 
    14.  *  
    15.  */  
    16. public class SpaceClient {  
    17.   
    18.     public static void main(String[] args) {  
    19.         String url = "http://192.168.0.9:8080/test/remote/SpaceHessian";  
    20.         HessianProxyFactory factory = new HessianProxyFactory();  
    21.         try {  
    22.             SpaceService spaceService = (SpaceService) factory.create(  
    23.                     SpaceService.class, url);  
    24.             System.out.println(spaceService.findSpace("testid"));  
    25.             System.out.println(spaceService.updateSpaceName("whatever"));  
    26.               
    27.             List spaceNames = spaceService.showSpaceNames();  
    28.             System.out.println("\r\nGet space names:");  
    29.             for (int i = 0; i < spaceNames.size(); i++) {  
    30.                 System.out.print(spaceNames.get(i) + ", ");  
    31.             }  
    32.             System.out.println();  
    33.             System.out.println("space names list finished");  
    34.         } catch (MalformedURLException e) {  
    35.             e.printStackTrace();  
    36.         }  
    37.     }  
    38. }  
     如果后台没有什么太大的问题,直接跑起来就可以测试了。
  8. 测试结果:
    Java代码   收藏代码
    1. Space:public name:roosher-space, private name:my-private-room, is actived:true,  
    2. lastUpdatedTime:1282196778538  
    3. true  
    4.   
    5. Get space names:  
    6. Hello space 0, Hello space 1, Hello space 2, Hello space 3, Hello space 4, Hello space 5  
    7. , Hello space 6, Hello space 7, Hello space 8, Hello space 9,  
    8. space names list finished  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值