Spring-WS 端点文档文字 wrapping/unwrapping
Spring-WS endpoints document literal wrapping/unwrapping
我正在与一个期望我们使用 WS-I 1.1 document/literal 包装消息的系统集成。我们有一个有效的解决方案,但似乎有更简单的方法来处理有效负载 wrapping/unwrapping.
我有一个端点如下:
@Endpoint
public class FooEndpoint
{
@Autowired
private FooService FooService;
@PayloadRoot(localPart = "Foo", namespace = "http://foo/service")
@ResponsePayload
public JAXBElement<FooAcknowledgementType> Foo(
@RequestPayload JAXBElement<FooRequestType> requestElement)
{
FooRequestType request = requestElement.getValue();
FooAcknowledgementType response = FooService.Foo(request);
// TODO: Find a better solution with the wrapped response
return new JAXBElement<FooAcknowledgementType>(new QName(
"http://foo/service", "FooAcknowledgement"),
FooAcknowledgementType.class, null, response);
}
}
定义合同的 WSDL 如下:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:tns="http://foo/service" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns="http://www.w3.org/2000/09/xmldsig#" xmlns:ns1="http://foo/schema"
name="Foo" targetNamespace="http://foo/service">
<wsdl:types>
<xsd:schema xmlns:s="http://foo/schema" targetNamespace="http://foo/service">
<xsd:import namespace="http://foo/schema" schemaLocation="foo_types.xsd" />
<xsd:element name="Foo" type="s:FooRequestType" />
<xsd:element name="FooAcknowledgement" type="s:FooAcknowledgementType" />
</xsd:schema>
</wsdl:types>
<wsdl:message name="FooRequest">
<wsdl:part name="parameter" element="tns:Foo" />
</wsdl:message>
<wsdl:message name="FooAcknowledgement">
<wsdl:part name="parameter" element="tns:FooAcknowledgement" />
</wsdl:message>
<wsdl:portType name="FooPortType">
<wsdl:operation name="Foo">
<wsdl:input message="tns:FooRequest" />
<wsdl:output message="tns:FooAcknowledgement" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="FooBinding" type="tns:FooPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="Foo">
<soap:operation soapAction="http://foo/serviceFoo" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Foo">
<wsdl:documentation>Foo web service</wsdl:documentation>
<wsdl:port name="FooService" binding="tns:FooBinding">
<soap:address location="http://localhost:8080/foo/services/Foo" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
我已经从上面端点 class 中引用的 foo_types.xsd 模式生成了 jaxb 对象。
问题是,当我们收到 document/literal 包装样式的 soap 消息时,soap 主体负载看起来像
<x:Foo>
<!-- elements from s:FooRequestType -->
</x:Foo>
并且我们需要像
这样的 soap body payload 来响应
<x:FooAcknowledgement>
<!-- elements from s:FooAcknowledgementType -->
</x:FooAcknowledgement>
Spring-WS 是否可以开箱即用?我们可以按原样使用代码使用和生成兼容的消息,但看起来这可能不是正确的方法,因为 http://docs.spring.io/spring-ws/site/reference/html/tutorial.html#tutorial.xsd[= 的 spring 文档中未引用这种样式17=]
我们的解决方案是通过我们的 jaxb bindings.xml,将命名空间和元素名称添加到 @XmlRootElement 注释中,例如
<jaxb:bindings node="xs:complexType[@name='fooType']">
<annox:annotate target="class">
<annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="FooAcknowledgement" namespace="http://foo/service"/>
</annox:annotate>
</jaxb:bindings>
我正在与一个期望我们使用 WS-I 1.1 document/literal 包装消息的系统集成。我们有一个有效的解决方案,但似乎有更简单的方法来处理有效负载 wrapping/unwrapping.
我有一个端点如下:
@Endpoint
public class FooEndpoint
{
@Autowired
private FooService FooService;
@PayloadRoot(localPart = "Foo", namespace = "http://foo/service")
@ResponsePayload
public JAXBElement<FooAcknowledgementType> Foo(
@RequestPayload JAXBElement<FooRequestType> requestElement)
{
FooRequestType request = requestElement.getValue();
FooAcknowledgementType response = FooService.Foo(request);
// TODO: Find a better solution with the wrapped response
return new JAXBElement<FooAcknowledgementType>(new QName(
"http://foo/service", "FooAcknowledgement"),
FooAcknowledgementType.class, null, response);
}
}
定义合同的 WSDL 如下:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:tns="http://foo/service" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns="http://www.w3.org/2000/09/xmldsig#" xmlns:ns1="http://foo/schema"
name="Foo" targetNamespace="http://foo/service">
<wsdl:types>
<xsd:schema xmlns:s="http://foo/schema" targetNamespace="http://foo/service">
<xsd:import namespace="http://foo/schema" schemaLocation="foo_types.xsd" />
<xsd:element name="Foo" type="s:FooRequestType" />
<xsd:element name="FooAcknowledgement" type="s:FooAcknowledgementType" />
</xsd:schema>
</wsdl:types>
<wsdl:message name="FooRequest">
<wsdl:part name="parameter" element="tns:Foo" />
</wsdl:message>
<wsdl:message name="FooAcknowledgement">
<wsdl:part name="parameter" element="tns:FooAcknowledgement" />
</wsdl:message>
<wsdl:portType name="FooPortType">
<wsdl:operation name="Foo">
<wsdl:input message="tns:FooRequest" />
<wsdl:output message="tns:FooAcknowledgement" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="FooBinding" type="tns:FooPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="Foo">
<soap:operation soapAction="http://foo/serviceFoo" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Foo">
<wsdl:documentation>Foo web service</wsdl:documentation>
<wsdl:port name="FooService" binding="tns:FooBinding">
<soap:address location="http://localhost:8080/foo/services/Foo" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
我已经从上面端点 class 中引用的 foo_types.xsd 模式生成了 jaxb 对象。
问题是,当我们收到 document/literal 包装样式的 soap 消息时,soap 主体负载看起来像
<x:Foo>
<!-- elements from s:FooRequestType -->
</x:Foo>
并且我们需要像
这样的 soap body payload 来响应<x:FooAcknowledgement>
<!-- elements from s:FooAcknowledgementType -->
</x:FooAcknowledgement>
Spring-WS 是否可以开箱即用?我们可以按原样使用代码使用和生成兼容的消息,但看起来这可能不是正确的方法,因为 http://docs.spring.io/spring-ws/site/reference/html/tutorial.html#tutorial.xsd[= 的 spring 文档中未引用这种样式17=]
我们的解决方案是通过我们的 jaxb bindings.xml,将命名空间和元素名称添加到 @XmlRootElement 注释中,例如
<jaxb:bindings node="xs:complexType[@name='fooType']">
<annox:annotate target="class">
<annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="FooAcknowledgement" namespace="http://foo/service"/>
</annox:annotate>
</jaxb:bindings>