在Spring-WS中向自定义SOAP头添加子元素

16

我正在使用Spring-WS调用SOAP webservice。这个webservice要求我在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个回答

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


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>

3
欢迎来到SO!请对您的代码进行解释,说明其功能以及如何回答问题。如果您得到了代码片段作为答案,您可能不知道该怎么做。您的回答应该提供指导,帮助提问者调试和解决问题。指出您代码背后的思想,有助于理解问题并应用或修改您的解决方案。 - Palec

1

我不太满意这个解决方案,但实际上你可以将消息转换为SOAPMessage,从而完全访问所有SAAJ api。从那里,您可以在头部内构建任何元素。


1
你的意思是类似于这篇帖子吗:https://dev59.com/MG855IYBdhLWcg3w_5gQ,在将消息转换为SOAPMessage后使用Transformer?我同意这并不是很令人愉悦或优雅。我想知道为什么。 - chris
1
-1 不算是真正的答案。顺便说一下,@chris提供的链接有好的解决方案。 - kaskelotti
1
你的回答,即使被标记为正确的,也没有帮助我们解决问题。 - marionmaiden

0

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

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接