我们可以在Spring WS中使用多个消息工厂吗?

时间:2011-07-21 11:31:39

标签: java spring soap streaming spring-ws

我最近解决了problem of the direct streaming with Spring WS,感谢Arjen的快速反应。诀窍是在Axiom消息工厂中禁用有效负载缓存。

我现在正遭受这个全局决定,我们要么为整个系统启用或禁用有效负载缓存。我们希望有流服务的web服务,还有一些能够进行验证(如果禁用了有效负载缓存,这是不可能的)

那么可以将特定端点映射到特定的消息工厂吗?使用Web服务客户端很容易,但端点呢?有什么想法吗?

谢谢!

2 个答案:

答案 0 :(得分:3)

你是对的,客户端很容易将特定的WebServiceMessageFactory实例传递给WebServiceTemplate构造函数。

无论如何,我想在服务器端也可以。 如果您可以使用不同的网址映射,我发现的最简单的方法是基于MessageDispatcherServlet中两个(或更多)差异web.xml的配置。然后,您只需要将您喜欢的WebServiceMessageFactory实例的特定bean名称作为init参数传递。像这样:

<servlet>
    <servlet-name>ws1</servlet-name>
    <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/conf/ws1-servlet.xml</param-value>
    </init-param>
    <init-param>
        <param-name>messageFactoryBeanName</param-name>
        <param-value>defaultMessageFactory</param-value>
    </init-param>
</servlet>

<servlet>
    <servlet-name>ws2</servlet-name>
    <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/conf/ws2-servlet.xml</param-value>
    </init-param>
    <init-param>
        <param-name>messageFactoryBeanName</param-name>
        <param-value>streamingMessageFactory</param-value>
    </init-param>
</servlet>

<servlet-mapping>
    <servlet-name>ws1</servlet-name>
    <url-pattern>/ws1</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>ws2</servlet-name>
    <url-pattern>/ws2</url-pattern>
</servlet-mapping>

然后,您只需将不同的消息工厂bean添加到spring-ws上下文中。

希望这有帮助。

答案 1 :(得分:1)

如果要在单个端点内切换messagefactory,可以通过扩展WebServiceMessageReceiverHandlerAdapter和覆盖getMessageFactory方法来实现。

  public class SwitchableMessageRecieverHandlerAdapter extends WebServiceMessageReceiverHandlerAdapter{

   private WebServiceMessageFactory alternateMessageFactory;

   private String switchOn;

   public void setSwitchOn(String switchOn) {
    this.switchOn = switchOn;
   }

   public String getSwitchOn() {
    return switchOn;
   }

   public WebServiceMessageFactory getAlternateMessageFactory() {
       return alternateMessageFactory;
   }

   public void setAlternateMessageFactory(WebServiceMessageFactory alternateMessageFactory) {
       this.alternateMessageFactory = alternateMessageFactory;
   }

    public void afterPropertiesSet() throws Exception {
        Assert.notNull(alternateMessageFactory, "alternateMessageFactory is required");
        Assert.notNull(switchOn, "switchOn parameter is required");
    }

    @Override
    public WebServiceMessageFactory getMessageFactory() {
        TransportContext transport = TransportContextHolder.getTransportContext();

        if(transport!=null && transport.getConnection() instanceof HttpServletConnection){
            HttpServletConnection httpCon = (HttpServletConnection)(transport.getConnection());
            if(getSwitchOn().equals(httpCon.getHttpServletRequest().getHeader("soapAction"))){
                return alternateMessageFactory;
            }
        }

        return super.getMessageFactory();

    }

}

现在,在您的上下文文件中配置SwitchableMessageRecieverHandlerAdapter,方法是提供您要使用的alternateMessageFactory和soap操作alternateMessageFactory

<bean id="messageFactory" class="org.springframework.ws.samples.mtom.service.AxiomMtomEnabledSoapMessageFactory">
        <property name="payloadCaching" value="true"/>
        <property name="attachmentCaching" value="true"/>
    </bean>

    <bean id="saajMessageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>

    <bean id="switchableMessageReciever" class="SwitchableMessageRecieverHandlerAdapter">
        <property name="alternateMessageFactory" ref="saajMessageFactory"/>
        <property name="switchOn" value="LoadImage"/>

    </bean>

现在通过在web.xml中添加init-param来通知MessageDispatcherServlet使用扩展的WebServiceMessageReceiverHandlerAdapter

<servlet>
    <servlet-name>spring-ws</servlet-name>
    <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
    <init-param>
      <param-name>transformWsdlLocations</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>messageReceiverHandlerAdapterBeanName</param-name>
        <param-value>switchableMessageReciever</param-value>
    </init-param>
  </servlet>