[英]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.