15

我正在使用 Spring-WS 调用 SOAP Web 服务。有问题的 Web 服务要求我在 SOAP 标头中传递一些信息,如下所示:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header>
      <CustomHeaderElement>
         <clientID>xyz</clientID>
         <wsdlVersion>1.0</wsdlVersion>
         <serviceType>ExampleService_v1</serviceType>
      </CustomHeaderElement>
   </soapenv:Header>
   <soapenv:Body>
   ...
   </soapenv:Body>
</soapenv:Envelope>

我已经想出了如何拥有顶级 CustomHeaderElement,但我在 Spring-WS API 中看不到任何允许我添加子元素的东西。这是我到目前为止所拥有的:

WebServiceTemplate template = ...;

template.marshalSendAndReceive(request, new WebServiceMessageCallback(){
    public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException{
        SoapMessage soapMessage = (SoapMessage)message;
        SoapHeader soapHeader = soapMessage.getSoapHeader();
        QName qName = new QName("CustomHeaderElement");
        SOAPHeaderElement headerElement = soapHeader.addHeaderElement(qName);
        //would like to do something like headerElement.addChild(clientIdNode);
    }
});

问题是 headerElement 似乎没有公开任何实际添加孩子的方法。我知道我可以添加一个属性,但这不是此服务调用所需要的。有谁知道我如何将必要的子元素添加到我的自定义标题中?

4

4 回答 4

8

我遇到了同样的问题,这是我的解决方案,但它只适用于简单的元素,而不适用于复杂的元素:

template.marshalSendAndReceive(request, new WebServiceMessageCallback(){
    public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException{
        SaajSoapMessage soapMessage = (SaajSoapMessage) message;
        SoapHeaderElement messageId =  soapMessage.getSoapHeader().addHeaderElement(new QName("http://www.w3.org/2005/08/addressing", "MessageID", "wsa"));
        messageId.setText("urn:abcdef1234");
    }
});

它产生以下 XML:

<SOAP-ENV:Header>
  <wsa:MessageID>urn:abcdef1234</wsa:MessageID>
</SOAP-ENV:Header>

顺便说一句javax.xml.soap.SOAPMessage,也可以工作,请参见此处:http ://docs.oracle.com/javaee/5/tutorial/doc/bnbhr.html#bnbia

于 2012-02-15T01:11:48.163 回答
3
final String datPrefix = "dat";
final String datNamespaceUri = "UPRS/Services/IProviderDataManagement/Datatypes";

final String mesPrefix = "mes";
final String mesNamespaceUri = "UPRS/Services/IProviderDataManagement/Messages";

SoapEnvelope se = s.getEnvelope();
se.addNamespaceDeclaration(mesPrefix,
        mesNamespaceUri);
se.addNamespaceDeclaration(datPrefix,
        datNamespaceUri);

SoapMessage s = (SoapMessage) message;

Element root = new Element("requestContext", mesPrefix, mesNamespaceUri);
Element child = new Element("commandId", datPrefix, datNamespaceUri).addContent(guid);
root.addContent(child);

TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new JDOMSource(root), s.getSoapHeader().getResult());

它产生了输出

<SOAP-ENV:Header>
        <mes:requestContext xmlns:mes="UPRS/Services/IProviderDataManagement/Messages">
            <dat:commandId xmlns:dat="UPRS/Services/IProviderDataManagement/Datatypes">ba7b1e13-8a06-49b6-a264-fc0298f55f4f</dat:commandId>
        </mes:requestContext>
    </SOAP-ENV:Header>
于 2014-02-17T11:50:40.240 回答
1

我对这个解决方案不满意,但事实证明,您实际上可以将消息转换为 SOAPMessage,从而使您可以完全访问所有 SAAJ api。从那里您可以在标题中构建您想要的任何元素。

于 2010-11-15T16:03:45.690 回答
0

我遇到了同样的问题,并使用以下代码段解决了它:

Result result = ((SoapMessage) message).getSoapHeader().getResult();
webServiceTemplate.getMarshaller().marshal(createCustomHeader(), result);

createCustomerHeader()方法创建一个从 XSD 生成的 JAXB bean。

于 2016-08-18T06:49:21.207 回答