URI
組み合わせてPayloadRoot
マッピングするものが必要です。残念ながら、Spring-Ws にはこのようなものはありません。しかし、非常に拡張可能であるため、これを実現するのは非常に簡単です。
TL;DR
実際の例については、GitHub のこのブランチを参照してください
詳細
org.springframework.ws.server.endpoint.MethodEndpoint
結合された URI+QName のインスタンスへのマッピングを作成する必要があります。また、既存の Spring-Ws 関数を複製するコードを最小限に抑える必要があります。
したがって、1) を使用せずに Spring-Ws アノテーションを明示的に構成する必要があります<sws:annotation-driven />
。
これはあなたの要件です(私のスキーマを使用):
<ws:dynamic-wsdl id="spml-readonly" portTypeName="SpmlReadOnlyService" locationUri="SpmlReadOnly">
<ws:xsd location="classpath:springws/model/schema.xsd" />
</ws:dynamic-wsdl>
<ws:dynamic-wsdl id="spml-crud" portTypeName="SpmlCrudService" locationUri="SpmlCrud">
<ws:xsd location="classpath:springws/model/schema.xsd" />
<ws:xsd location="classpath:springws/model/schema2.xsd" />
</ws:dynamic-wsdl>
手動で行う必要があるのはこれだけで、通常は<sws:annotation-driven />
(1 つの JAXB マーシャラーを備えた 1 つのアダプター)によって構成されます。
<bean class="org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter">
<property name="methodArgumentResolvers">
<list>
<ref local="marshallingPayloadMethodProcessor"/>
</list>
</property>
<property name="methodReturnValueHandlers">
<list>
<ref local="marshallingPayloadMethodProcessor"/>
</list>
</property>
</bean>
<bean id="marshallingPayloadMethodProcessor" class="org.springframework.ws.server.endpoint.adapter.method.MarshallingPayloadMethodProcessor">
<property name="marshaller" ref="marshaller" />
<property name="unmarshaller" ref="marshaller" />
</bean>
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="contextPaths">
<list>
<value>springws.model</value>
</list>
</property>
</bean>
これはカスタム マッピングです。
<bean class="springws.PathAndPayloadRootAnnotationEndpointMapping" />
そして2)独自のマッピングを作成する必要があります
public class PathAndPayloadRootAnnotationEndpointMapping extends PayloadRootAnnotationMethodEndpointMapping
{
@Override
protected QName getLookupKeyForMessage(MessageContext messageContext) throws Exception
{
String urlPart = "";
QName payloadRootPart = super.getLookupKeyForMessage(messageContext);
TransportContext transportContext = TransportContextHolder.getTransportContext();
if (transportContext != null) {
WebServiceConnection connection = transportContext.getConnection();
if (connection != null && connection instanceof HttpServletConnection) {
String requestURI = ((HttpServletConnection)connection).getHttpServletRequest().getRequestURI();
String contextPath = ((HttpServletConnection)connection).getHttpServletRequest().getContextPath();
urlPart = requestURI.substring(contextPath.length());
}
}
return new QName(payloadRootPart.getNamespaceURI(), urlPart + "/" + payloadRootPart.getLocalPart());
}
@Override
protected List<QName> getLookupKeysForMethod(Method method)
{
List<QName> result = new ArrayList<QName>();
RequestMapping rm = AnnotationUtils.findAnnotation(method.getDeclaringClass(), RequestMapping.class);
String urlPart = rm == null || rm.value().length != 1 ? "" : rm.value()[0];
List<QName> methodPart = super.getLookupKeysForMethod(method);
for (QName qName : methodPart) {
result.add(new QName(qName.getNamespaceURI(), urlPart + "/" + qName.getLocalPart()));
}
return result;
}
}
拡張しorg.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping
ます。そして、エンドポイント URI から抽出された情報を使用して、メッセージのキー(ペイロード ルート要素の QName) を拡張するだけです。そのためにSpring の@org.springframework.web.bind.annotation.RequestMapping
アノテーションを使用しましたが、ハックだと思う人が独自のアノテーションを作成する可能性があります。
したがって、次のようなエンドポイントの場合:
@org.springframework.ws.server.endpoint.annotation.Endpoint
@RequestMapping("/ws/SpmlReadOnly")
public class Endpoint1
{
@ResponsePayload
@PayloadRoot(namespace = "urn:test", localPart = "method1Request")
public Response2 method(@RequestPayload Request1 request) throws Exception
{
return new Response2("e1 m1");
}
}
キーはそうではありません:
namespace = urn:test
localName = method1Request
でもこれは:
namespace = urn:test
localName = /ws/SpmlReadOnly/method1Request
このprotected QName getLookupKeyForMessage(MessageContext messageContext)
メソッドは、マッピング URI が WAR コンテキストから独立していることを保証し、アプリケーションがデプロイされます。