【问题标题】:Add child elements to custom SOAP header in Spring-WS在 Spring-WS 中将子元素添加到自定义 SOAP 标头
【发布时间】:2010-10-27 16:26:09
【问题描述】:

我正在使用 Spring-WS 调用 SOAP 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 似乎没有公开任何实际添加孩子的方法。我知道我可以添加一个属性,但这不是此服务调用所需要的。有谁知道我如何将必要的子元素添加到我的自定义标题中?

【问题讨论】:

    标签: soap header spring-ws saaj


    【解决方案1】:

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

    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

    【讨论】:

      【解决方案2】:
      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>
      

      【讨论】:

      • 欢迎来到 SO!请说明您的代码的作用以及它如何回答问题。如果您得到一个代码 sn-p 作为答案,您可能不知道如何处理它。答案应为 OP 提供有关如何调试和解决问题的指导。指出您的代码背后的想法是什么,对理解问题以及应用或修改您的解决方案有很大帮助。
      【解决方案3】:

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

      【讨论】:

      • 您的意思是不是类似于这篇文章:stackoverflow.com/questions/4046075/… 在将消息转换为 SOAPMessage 后使用 Transformer 的地方?我同意这既不讨人喜欢也不优雅。我想知道为什么。
      • -1 不是真正的答案。附言@chris 提供的链接有很好的解决方案。
      • 你的答案,即使标记为正确的,也对我们没有任何帮助。
      【解决方案4】:

      我遇到了同样的问题,用下面的 sn-p 解决了:

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

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

      【讨论】:

        猜你喜欢
        • 2014-10-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-02
        • 2012-05-17
        • 1970-01-01
        相关资源
        最近更新 更多