Можем ли мы использовать несколько фабрик сообщений в Spring WS? - PullRequest
2 голосов
/ 21 июля 2011

Я недавно решил проблему прямой потоковой передачи с Spring WS , спасибо Арьену за быстрый ответ.Хитрость заключалась в том, чтобы отключить кэширование полезной нагрузки в фабрике сообщений Axiom.

Сейчас я страдаю от этого глобального решения, мы должны включить или отключить кэширование полезной нагрузки для всей системы.Мы хотели бы иметь веб-сервисы с потоковой передачей, а также некоторые, которые обеспечивают проверку (что невозможно, если кэширование полезной нагрузки отключено)

Так возможно ли сопоставить конкретную конечную точку с конкретной фабрикой сообщений?Это легко сделать с клиентами веб-сервисов, но как насчет конечных точек?Есть идеи?

Спасибо!

Ответы [ 2 ]

3 голосов
/ 21 июля 2011

Вы правы, на стороне клиента очень просто передать конкретный экземпляр WebServiceMessageFactory в конструктор WebServiceTemplate.

Во всяком случае, я думаю, что это также возможно на стороне сервера. Если вы можете использовать различные отображения URL, самый простой способ, который я обнаружил, основан на конфигурации двух (или более) различий MessageDispatcherServlet в вашем web.xml. Затем вам просто нужно передать в качестве параметра init конкретное имя компонента для WebServiceMessageFactory экземпляра, который вы предпочитаете. Примерно так:

<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>

Затем вам просто нужно добавить различные фабричные бины сообщений в контекст spring-ws.

Надеюсь, это поможет.

1 голос
/ 30 октября 2013

Если вы хотите переключить фабрику сообщений в пределах одной конечной точки, вы можете добиться этого, расширив 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 и действия мыла, для которых вы хотите использовать 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>

Теперь сообщите MessageDispatcherServlet использовать расширенный WebServiceMessageReceiverHandlerAdapter, добавив init-param в web.xml

<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>
...