之前使用Spring的BeanNameUrlHandlerMapping,对Hessian的处理是比较简单的,这里不多说了。
那么如果提供ResuFul 通过Spring的 Annotation功能呢?据我所知,Spring支持的Hessian目前还不支持Annotation配置。
好吧,想想有没有别的办法:
因为 Annotation 的 restful 需要启动这两个类:
< bean class ="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
< bean class ="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
这样的话,Spring就不再使用默认BeanNameUrlHandlerMapping,而是完全通过 DefaultAnnotationHandlerMapping 进行Mapping.
但据我所知,Hessian与Spring整合必须通过 org.springframework.remoting.caucho.HessianServiceExporter 进行兼容。
那么怎么将HessianServiceExporter Annotation呢?首先想到了使用反射,OK,没有问题,通过cglib一定可以做的。
第二,通知显性的定义 BeanNameUrlHandlerMapping, 之后再进行order,是不是也可以的。
我觉得第二种开发成本会小一些,那么使用第二种方式。
< bean class ="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" >
< property name ="order" value ="1" />
</ bean >
< bean class ="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" >
< property name ="order" value ="2" />
</ bean >
运行一下,还是不好用,哦~~原来的 AnnotationMethodHandlerAdapter 再捣鬼,它不支持Servlet方式,那么好吧,对于hessian的处理,使用org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter吧。这个肯定是好用的。
全部代码为:
web.xml:
< servlet >
< servlet-name > SillServlet </ servlet-name >
< servlet-class > org.springframework.web.servlet.DispatcherServlet </ servlet-class >
< init-param >
< param-name > contextConfigLocation </ param-name >
< param-value > /WEB-INF/applicationContext/mvc-config.xml,/WEB-INF/applicationContext/bean-hessian.xml </ param-value >
</ init-param >
< load-on-startup > 1 </ load-on-startup >
</ servlet >
< servlet-mapping >
< servlet-name > SillServlet </ servlet-name >
< url-pattern > /app/* </ url-pattern >
</ servlet-mapping >
mvc-config.xml:
<!-- Configures support for @Controllers -->
< mvc:annotation-driven />
<!-- 启动springmvc的注解映射功能 -->
< bean class ="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" >
< property name ="order" value ="1" />
</ bean >
<!-- Hessian 启动BeanNameMapping 映射功能 -->
< bean class ="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" >
< property name ="defaultHandler" ref ="httpRequestHandlerAdapter" />
< property name ="order" value ="2" />
</ bean >
<!-- 启动springmvc的注解功能 -->
< bean class ="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<!-- 处理httpRequest的Adapter -->
< bean id ="httpRequestHandlerAdapter" class ="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter" ></ bean >
<!-- spring 对 com.*.*.*.* 进行扫描 -->
< context:component-scan base-package ="com.*.*.*.*" />
bean-hessian.xml: 正常配置,HessianBean的配置没有变化
< bean name ="/hessianResultService" class ="org.springframework.remoting.caucho.HessianServiceExporter" >
< property name ="service" ref ="resultHessianService" />
< property name ="serviceInterface" value ="com.interface.*" />
</ bean >
< bean id ="resultHessianService" class ="com.interfaceimpl.*" />
< bean name ="/hessianConditionService" class ="org.springframework.remoting.caucho.HessianServiceExporter" >
< property name ="service" ref ="conditionHessianService" />
< property name ="serviceInterface" value ="com.interface.*" />
</ bean >
< bean id ="conditionHessianService" class ="com.interfaceimpl.*" />
RunTest,OK~!
重点回顾:
1.Hessian需要提供Servlet支撑,那么 AnnotationMethodHandlerAdapter 无法满足,需要使用 HttpRequestHandlerAdapter。
2.必须使用显性的BeanNameUrlHandlerMapping配置,否则可以使用SimpleUrlHandlerMapping,但是配置比较麻烦,维护成本比较高。
================================================================================
还有另外一种方式配置也可以使用(目前我就使用的这种方式)
Key: 使用不同的Servlet来处理Hessian请求与一般请求即可。
看下代码:
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" xmlns:web ="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation ="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version ="2.5" >
< listener >
< listener-class > org.springframework.web.context.ContextLoaderListener </ listener-class >
</ listener >
<!-- Reads request input using UTF-8 encoding -->
< filter >
< filter-name > characterEncodingFilter </ filter-name >
< filter-class > org.springframework.web.filter.CharacterEncodingFilter </ filter-class >
< init-param >
< param-name > encoding </ param-name >
< param-value > UTF-8 </ param-value >
</ init-param >
< init-param >
< param-name > forceEncoding </ param-name >
< param-value > true </ param-value >
</ init-param >
</ filter >
<!-- Log4j 指定 Log4J 配置文件的地址 -->
< context-param >
< param-name > log4jConfigLocation </ param-name >
< param-value > /WEB-INF/log4j.properties </ param-value >
</ context-param >
< context-param >
< param-name > contextConfigLocation </ param-name >
< param-value > classpath*:/spring-dao/spring-*.xml,/WEB-INF/applicationContext/applicationContext.xml </ param-value >
</ context-param >
< servlet >
< servlet-name > SillServlet </ servlet-name >
< servlet-class > org.springframework.web.servlet.DispatcherServlet </ servlet-class >
< init-param >
< param-name > contextConfigLocation </ param-name >
< param-value > /WEB-INF/applicationContext/mvc-config.xml </ param-value >
</ init-param >
</ servlet >
< servlet-mapping >
< servlet-name > SillServlet </ servlet-name >
< url-pattern > /app/* </ url-pattern >
</ servlet-mapping >
< servlet >
< servlet-name > Remoting </ servlet-name >
< servlet-class > org.springframework.web.servlet.DispatcherServlet </ servlet-class >
< init-param >
< param-name > contextConfigLocation </ param-name >
< param-value > /WEB-INF/applicationContext/bean-hessian.xml </ param-value >
</ init-param >
</ servlet >
< servlet-mapping >
< servlet-name > Remoting </ servlet-name >
< url-pattern > /remoting/* </ url-pattern >
</ servlet-mapping >
</ web-app >
mvc-config.xml:
<? 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:mvc ="http://www.springframework.org/schema/mvc"
xmlns:context ="http://www.springframework.org/schema/context" xmlns:p ="http://www.springframework.org/schema/p"
xmlns:util ="http://www.springframework.org/schema/util"
xsi:schemaLocation ="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd" >
< mvc:annotation-driven />
< bean
class ="org.springframework.web.servlet.view.InternalResourceViewResolver" >
< property name ="prefix" value ="/WEB-INF/views/" />
< property name ="suffix" value =".jsp" />
</ bean >
<!-- 启动springmvc的注解映射功能 -->
< bean
class ="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" >
</ bean >
<!-- 只针对action包中的controller进行扫描 -->
< context:component-scan base-package ="com.*.*.action" />
< context:annotation-config />
<!-- Application Message Bundle -->
< bean id ="messageSource"
class ="org.springframework.context.support.ReloadableResourceBundleMessageSource" >
< property name ="basenames" >
< list >
< value > /WEB-INF/messages/messages </ value >
< value > /WEB-INF/messages/expMessages </ value >
< value > /WEB-INF/messages/chartMessages </ value >
</ list >
</ property >
< property name ="cacheSeconds" value ="-1" />
</ bean >
</ beans >
bean-hessian.xml:
<? 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"
xmlns:aop ="http://www.springframework.org/schema/aop" xmlns:tx ="http://www.springframework.org/schema/tx"
xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd" >
<!-- 必要配置项 -->
<!-- 扫描并加注HessianService 使用的bean -->
< context:annotation-config />
<!-- Hessian 启动BeanNameMapping 映射功能,以httpRequest作为处理Adapter -->
< bean
class ="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" >
< property name ="defaultHandler" ref ="httpRequestHandlerAdapter" />
</ bean >
<!-- Hessian 方式以Http进行传递 -->
< bean id ="httpRequestHandlerAdapter"
class ="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter" />
<!-- 以下为业务Bean -->
<!-- Hadoop计算完后 发布Result的 Remote Server -->
< bean name ="/hessianResultService"
class ="org.springframework.remoting.caucho.HessianServiceExporter" >
< property name ="service" ref ="resultHessianService" />
< property name ="serviceInterface"
value ="com.*.*.remote.hessian.HessianResultService" />
</ bean >
< bean id ="resultHessianService"
class ="com.*.*sill.job.service.export.HessianResultServiceHandler" />
< bean name ="/hessianConditionService"
class ="org.springframework.remoting.caucho.HessianServiceExporter" >
< property name ="service" ref ="conditionHessianService" />
< property name ="serviceInterface"
value ="com.*.*.remote.hessian.HessianConditionService" />
</ bean >
< bean id ="conditionHessianService"
class ="com.*.*.sill.job.service.export.HessianConditionServiceHandler" />
</ beans >
这样做的好处是可以进行分别处理HttpRequestHandlerAdapter 与 AnnotationMethodHandlerAdapter,不需要进行order控制,且有更大的灵活性。
对Hessian的增改与其他业务无关。
大家可以试试,如果有更好的方式请赐教~