修改SoapHandler中的Soap标头

时间:2015-03-04 11:21:03

标签: java web-services soap soapheader

我正在尝试修改soap标头,我希望标头像这样

<soapenv:Header xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
                        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <ns:authnHeader soapenv:mustUnderstand="0" xmlns:ns="http://webservices.averittexpress.com/authn">
                <Username>xxxxxxxx</Username>
                <Password>xxxxxxxx</Password>
            </ns:authnHeader>

这是我迄今为止所做的......

SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
SOAPHeader header = envelope.getHeader();

    header.addAttribute(new QName("xmlns:soapenc"), "http://schemas.xmlsoap.org/soap/encoding/");
    header.addAttribute(new QName("xmlns:xsd"), "http://www.w3.org/2001/XMLSchema");
    header.addAttribute(new QName("xmlns:xsi"), "http://www.w3.org/2001/XMLSchema-instance");

SOAPElement authnHeader = header.addChildElement("authnHeader", "ns" , "http://webservices.averittexpress.com/authn");

authnHeader.addAttribute(new QName("soapenv:mustUnderstand"), "0");

但我得到了

  

org.w3c.dom.DOMException:NAMESPACE_ERR:尝试创建   或者以不正确的方式更改对象   命名空间。

首先是header.addAttribute。

请帮忙。

我的导入声明

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.HandlerResolver;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.PortInfo;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

2 个答案:

答案 0 :(得分:2)

您收到此错误是因为您尝试在SOAP标头中定义命名空间属性。命名空间属性xmlns 必须在SOAP信封中定义。所以你真正想要的XML SOAP信封看起来像这样:

<soap:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soap:Header>
        <ns:authnHeader soapenv:mustUnderstand="0" xmlns:ns="http://webservices.averittexpress.com/authn">
            <Username>xxxxxxxx</Username>
            <Password>xxxxxxxx</Password>
        </ns:authnHeader>
    </soap:Header>
    <soap:Body>
        <!-- your content goes here -->
    </soap:Body>
</soap:Envelope>

根据conventions,如果您的XML没有在信封中提供SOAP命名空间,应用程序可能会拒绝您的SOAP消息。

作为参考,我花了大约3个小时试图找到一个代码示例,其中有人在SOAP标头上调用header.addAttribute(),我甚至找不到一个。

答案 1 :(得分:0)

终于有了一些运气。

此代码有效

Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

if(outboundProperty.booleanValue())
{

   try
    {
         SOAPHeader header = context.getMessage().getSOAPPart().getEnvelope().getHeader();

         SOAPFactory soapFactory = SOAPFactory.newInstance();
         SOAPElement authnHeader = soapFactory.createElement("authnHeader", "ns", "http://webservices.averittexpress.com/authn");

         SOAPElement username = authnHeader.addChildElement("Username");
         username.setTextContent("xxxxxxx");

         SOAPElement password = authnHeader.addChildElement("Password");
         password.setTextContent("xxxxxxx");

         header.addChildElement(authnHeader);
    }
    catch(Exception e)
    {
       e.printStackTrace();
    }
}

添加标题后不要忘记保存邮件

context.getMessage().saveChanges();

context.getMessage().writeTo(System.out);
如果进行了任何更改,

也会保存消息。