Spring3.0.2 使用全Annotation 与 Hessian 兼容配置

之前使用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的增改与其他业务无关。

大家可以试试,如果有更好的方式请赐教~

原文地址:https://www.cnblogs.com/yangwn/p/1789213.html