繁体   English   中英

Jaxb为终端指定Marshaller

[英]Jaxb specify Marshaller for Endpoint

我正在使用Spring框架。

我有多个混搭程序和多个端点。 因为我有多个编组任务,所以编组器的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>

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

谢谢你的帮助! :)

我最终扩展了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。

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

只需澄清已接受答案的某些点,就可以使引用做Endpoint,就像接收普通端点一样,将端点作为参数接收:

@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 {
   //...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM