带有javax.xml.soap的SOAP消息 - 名称空间错误?

Les*_*ess 4 java asp.net soap web-services soapui

以下是我应该从我的java Web应用程序调用的.NET Web服务的通用示例SOAP请求:

<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
 <soap:Body>
  <setAMRequestData xmlns="http://tempuri.org/">
    <id>int</id>
  </setAMRequestData>
 </soap:Body>
</soap:Envelope>
Run Code Online (Sandbox Code Playgroud)

我可以使用以下代码段从java控制台应用程序生成类似的东西:

import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
...
SOAPConnectionFactory sfc = SOAPConnectionFactory.newInstance();
SOAPConnection connection = sfc.createConnection();
MessageFactory mf = MessageFactory.newInstance();
SOAPMessage sm = mf.createMessage();

SOAPHeader sh = sm.getSOAPHeader();
SOAPBody sb = sm.getSOAPBody();
sh.detachNode();

QName bodyName = new QName("http://tempuri.org/", "setAMRequestData", XMLConstants.DEFAULT_NS_PREFIX);
SOAPBodyElement bodyElement = sb.addBodyElement(bodyName);
QName n = new QName("id");                                          
SOAPElement quotation = bodyElement.addChildElement(n);
quotation.addTextNode("121152");
Run Code Online (Sandbox Code Playgroud)

结果是以下XML:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
 <SOAP-ENV:Body>
  <setAMRequestData xmlns="http://tempuri.org/">
   <id>121152</id>
  </setAMRequestData>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Run Code Online (Sandbox Code Playgroud)

这会调用该服务.接下来,我使用soapUI尝试调用此服务,它从WSDL生成soap消息(它信封中的名称空间声明中的前一个和前缀不同):

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:tem="http://tempuri.org/">
 <soapenv:Header/>
  <soapenv:Body>
   <tem:setAMRequestData>
     <tem:id>?</tem:id>
   </tem:setAMRequestData>
  </soapenv:Body>
 </soapenv:Envelope>
Run Code Online (Sandbox Code Playgroud)

这也适用于soapUI.但最后,当我尝试使用此代码序列重新创建此形式的soap消息时:

// factories and stuff, like in the example above
SOAPPart part = sm.getSOAPPart();
SOAPEnvelope envelope = part.getEnvelope();
envelope.addNamespaceDeclaration("tem", "http://tempuri.org/");

SOAPHeader sh = sm.getSOAPHeader();
SOAPBody sb = sm.getSOAPBody();
sh.detachNode();

QName bodyName = new QName(null, "setAMRequestData", "tem");
SOAPBodyElement bodyElement = sb.addBodyElement(bodyName);
QName n = new QName(null, "id", "tem");
SOAPElement quotation = bodyElement.addChildElement(n);
quotation.addTextNode("7028");
Run Code Online (Sandbox Code Playgroud)

我在SOAPElement引号= bodyElement.addChildElement(n)中得到以下异常; :

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

无论我尝试了什么,我根本无法为id元素设置"tem"前缀......这里发生了什么?

谢谢.

Jör*_*ann 7

您正在将名称空间uri绑定到前缀,然后尝试创建具有相同前缀但具有空名称空间uri的元素:

envelope.addNamespaceDeclaration("tem", "http://tempuri.org/");
...
QName bodyName = new QName(null, "setAMRequestData", "tem");
Run Code Online (Sandbox Code Playgroud)

元素由名称空间uri和本地名称的组合标识.要解决此问题,您必须在您创建的每个元素上指定命名空间:

QName bodyName = new QName("http://tempuri.org/", "setAMRequestData", "tem");
...
QName n = new QName("http://tempuri.org/", "id", "tem");
Run Code Online (Sandbox Code Playgroud)