【问题标题】:Jaxb specify Marshaller for EndpointJaxb 为 Endpoint 指定 Marshaller
【发布时间】:2014-03-19 13:43:56
【问题描述】:

我正在使用 Spring 框架。

我有多个 mashaller 和多个端点。我的编组器的 Jaxb 上下文是使用 xml 绑定文件(使用 eclipselink-oxm-xml jaxbContextProperties)定义的,因为我有多个编组任务。使用注释不是一个好的解决方案,因为同一个对象需要不同的编组/解组过程,具体取决于端点。

我目前对单个 JaxbMarshaller 和 Endpoint 的配置如下所示:

<sws:annotation-driven marshaller="marshallerA" unmarshaller="marshallerA"/>        

    <bean id="loggingInterceptor"
        class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>


    <bean id="messageReceiver"
        class="org.springframework.ws.soap.server.SoapMessageDispatcher">
        <property name="endpointAdapters">
            <list>
                <ref bean="defaultMethodEndpointAdapter" />
            </list>
        </property>
    </bean> 

    <bean id="defaultMethodEndpointAdapter" 
        class="org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter">
        <property name="methodReturnValueHandlers">
            <list>
                <ref bean="marshallingPayloadMethodProcessor"/>
            </list>
        </property>
        <property name="methodArgumentResolvers">
            <list>
                <ref bean="marshallingPayloadMethodProcessor"/>
            </list>
        </property>     
    </bean>  


    <bean id="marshallingPayloadMethodProcessor"
        class="org.springframework.ws.server.endpoint.adapter.method.MarshallingPayloadMethodProcessor">
        <constructor-arg ref="marshallerA" />
        <constructor-arg ref="marshallerA" />
    </bean> 


    <bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">
        <property name="order" value="1" />
    </bean>

    <sws:dynamic-wsdl id="myEndpointA"
        portTypeName="WebService"
        locationUri="/ws/myEndpointServiceA/"
        targetNamespace="http://company.com/schema/webServices" >

        <sws:xsd location="classpath:/path/to/schema/mySchemaA.xsd"/>

    </sws:dynamic-wsdl>

    <bean id="marshallerA" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
        <property name="contextPath" value="x.y.z:x.y.w"/>
            <property name="jaxbContextProperties">
            <util:map>
                <entry key="eclipselink-oxm-xml">
                    <list>
                         <value>file:/bindingFileOne.xml</value>
                         <value>file:/bindingFileTwo.xml</value>
                         <value>file:/bindingFileThree.xml</value>    
                    </list>
                </entry>
            </util:map>
        </property>
    </bean>

现在假设我有第二个端点和第二个编组器,我如何强制端点使用特定的编组器?

感谢您的帮助! :)

【问题讨论】:

    标签: xml spring jaxb moxy endpoint


    【解决方案1】:

    我最终扩展了 DefaultMethodEndpointAdapter,创建了 SpecificEndpointAdapter。我只需要重写一个方法,实现如下:

    public class SpecificEndpointAdapter extends DefaultMethodEndpointAdapter {
        private List<Object> acceptedEndpoints;
    
        public void setAcceptedEndpoints(List<Object> acceptedEndpoints) {
            this.acceptedEndpoints = acceptedEndpoints;
        }
    
        @Override
            protected boolean supportsInternal(MethodEndpoint methodEndpoint) {
            if(acceptedEndpoints.contains(methodEndpoint.getBean()))
                return super.supportsInternal(methodEndpoint);
            return false;
        }
    }
    

    在我的上下文文件中,这允许我将端点适配器限制为特定端点,从而具有特定的编组器:

    <bean id="serviceAEndpointAdapter" class="my.package.SpecificEndpointAdapter">
        <property name="acceptedEndpoints">
            <list>
                <ref bean="serviceAEndpoint"/>
            </list>
        </property>
        <property name="methodReturnValueHandlers">
            <list>
                <ref bean="serviceA.marshallingPayloadMethodProcessor"/>
            </list>
        </property>
        <property name="methodArgumentResolvers">
            <list>
                <ref bean="serviceA.marshallingPayloadMethodProcessor"/>
            </list>
        </property>     
    </bean>    
    
    <bean id="serviceBEndpointAdapter" class="my.package.SpecificEndpointAdapter">
        <property name="acceptedEndpoints">
            <list>
                <ref bean="serviceBEndpoint"/>
            </list>
        </property>      
        <property name="methodReturnValueHandlers">
            <list>
                <ref bean="serviceB.marshallingPayloadMethodProcessor"/>
            </list>
        </property>
        <property name="methodArgumentResolvers">
            <list>
                <ref bean="serviceB.marshallingPayloadMethodProcessor"/>
            </list>
        </property>     
    </bean>    
    

    在我的 MarhsallingPayloadProcessor 中,我现在可以声明要使用的编组器。请注意,我最终使用 bean id 作为 SpecificEndpointAdapter 引用,因此如果您使用注释,则需要找出该端点的 bean id。

    我希望这对遇到相同问题的人有所帮助,如果答案需要更多说明,请告诉我。

    【讨论】:

      【解决方案2】:

      只是澄清一些已接受的答案,您可以让引用做端点,只是作为参数接收端点,就像一个普通的bean:

      @Bean
      public SpecificEndpointAdapter csvEndpointAdapter(MyEndpoint myEndpoint) {
      
          List<MethodArgumentResolver> argumentResolvers =
                  new ArrayList<>();
          argumentResolvers.add(methodProcessor());
      
          List<MethodReturnValueHandler> returnValueHandlers =
                  new ArrayList<>();
          returnValueHandlers.add(methodProcessor());
      
          SpecificEndpointAdapter specificEndpointAdapter = new SpecificEndpointAdapter();
          specificEndpointAdapter.setMethodArgumentResolvers(argumentResolvers);
          specificEndpointAdapter.setMethodReturnValueHandlers(returnValueHandlers);
          specificEndpointAdapter.setAcceptedEndpoints(Arrays.asList(myEndpoint));
      
          return specificEndpointAdapter;
      }
      
      private MarshallingPayloadMethodProcessor methodProcessor() {
          return new MarshallingPayloadMethodProcessor(marshaller());
      }
      
      private Jaxb2Marshaller marshaller() {
          Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
          marshaller.setContextPath("com.company.application");
          marshaller.setMtomEnabled(true);
          return marshaller;
      }
      

      MyEndpoint:

      @Endpoint
      public class MyEndpoint {
         //...
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-24
        • 1970-01-01
        • 1970-01-01
        • 2015-06-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-20
        相关资源
        最近更新 更多