之前使用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的增改与其他业务无关。
大家可以试试,如果有更好的方式请赐教~