24.4 使用HTTP调用器暴露服务

与使用自身序列化机制的轻量级协议Hessian相反,Spring HTTP调用器使用标准Java序列化机制通过HTTP暴露业务。如果你的参数或返回值是复杂类型,并且不能通过Hessian的序列化机制进行序列化,HTTP调用器就很有优势(请参阅下一节,以便在选择远程处理技术时进行更多考虑)。

在底层,Spring使用JDK提供的标准工具或Commons的HttpComponents来实现HTTP调用。如果你需要更先进和更易用的功能,请使用后者。你可以参考 hc.apache.org/httpcomponents-client-ga/ 以获取更多信息。

24.4.1 暴露服务对象

为服务对象设置HTTP调用器基础架构类似于使用Hessian进行相同操作的方式。就象为Hessian支持提供的HessianServiceExporter,Spring的HTTP调用器提供了org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter。 为了在Spring Web MVC的DispatcherServlet中暴露AccountService(之前章节提及过), 需要在调度程序的应用程序上下文中使用以下配置:

  1. <bean name="/AccountService" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
  2. <property name="service" ref="accountService"/>
  3. <property name="serviceInterface" value="example.AccountService"/>
  4. </bean>

如Hessian章节部分所述,这个导出器定义将通过DispatcherServlet的标准映射工具暴露出来。 或者, 在你的根应用上下文中(比如’WEB-INF/applicationContext.xml’)创建一个HttpInvokerServiceExporter:

  1. <bean name="accountExporter" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
  2. <property name="service" ref="accountService"/>
  3. <property name="serviceInterface" value="example.AccountService"/>
  4. </bean>

此外,在’web.xml’中为该导出器定义相应的servlet ,其中servlet名称与目标导出器的bean名称相匹配:

  1. <servlet>
  2. <servlet-name>accountExporter</servlet-name>
  3. <servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
  4. </servlet>
  5. <servlet-mapping>
  6. <servlet-name>accountExporter</servlet-name>
  7. <url-pattern>/remoting/AccountService</url-pattern>
  8. </servlet-mapping>

如果你在一个servlet容器之外运行程序和使用Oracle的Java6, 那么你可以使用内置的HTTP服务器实现。你可以配置SimpleHttpServerFactoryBean和SimpleHttpInvokerServiceExporter在一起,像下面这个例子一样:

  1. <bean name="accountExporter"
  2. class="org.springframework.remoting.httpinvoker.SimpleHttpInvokerServiceExporter">
  3. <property name="service" ref="accountService"/>
  4. <property name="serviceInterface" value="example.AccountService"/>
  5. </bean>
  6. <bean id="httpServer"
  7. class="org.springframework.remoting.support.SimpleHttpServerFactoryBean">
  8. <property name="contexts">
  9. <util:map>
  10. <entry key="/remoting/AccountService" value-ref="accountExporter"/>
  11. </util:map>
  12. </property>
  13. <property name="port" value="8080" />
  14. </bean>

24.4.2 在客户端连接服务

同样,从客户端连接业务与你使用Hessian所做的很相似。使用代理,Spring可以将你的HTTP POST调用请求转换成被暴露服务的URL。

  1. <bean id="httpInvokerProxy" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
  2. <property name="serviceUrl" value="http://remotehost:8080/remoting/AccountService"/>
  3. <property name="serviceInterface" value="example.AccountService"/>
  4. </bean>

如前所述,你可以选择要使用的HTTP客户端。默认情况下,HttpInvokerProxy使用JDK的HTTP功能,但你也可以通过设置httpInvokerRequestExecutor属性来使用ApacheHttpComponents客户端:

  1. <property name="httpInvokerRequestExecutor">
  2. <bean class="org.springframework.remoting.httpinvoker.HttpComponentsHttpInvokerRequestExecutor"/>
  3. </property>