2011-08-22 91 views
3

以下是.NET Web服务的通用样本SOAP请求,我应该从我的Java web应用程序调用:带有javax.xml.soap的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> 

我能够使用这个代码段产生从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"); 

结果是下面的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> 

这调用服务。接下来,我用的soapUI尝试调用这个服务,它生成的SOAP消息从WSDL这样的(它不同于在信封中的命名空间声明以前,和前缀):

<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> 

这也来自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"); 

我在线路的SOAPElement报价以下异常= bodyElement.addChildElement(N);

org.w3c.dom.DOMException中:NAMESPACE_ERR:试图创建或在某种程度上这是不正确关于命名空间改变的对象。

不管我试过了,我根本无法设置“TEM”前缀为ID元素......这到底是怎么回事?

谢谢。

回答

5

你是一个命名空间URI绑定到一个前缀,后来尝试用相同的前缀,但空命名空间URI创建一个元素:

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

的元素是由空间URI和本地的组合标识名称。为了解决这个问题,你必须指定每个元素的命名空间创建:

QName bodyName = new QName("http://tempuri.org/", "setAMRequestData", "tem"); 
... 
QName n = new QName("http://tempuri.org/", "id", "tem"); 
+0

是的,这解决了它。显然我遇到了javax.xml.soap用法的一些不好的例子...谢谢。 – Less

1

不要让所有的工作,因为在XML走出你的应用程序看起来不完全一样(特别是与命名空间前缀)作为SoapUI提出的请求。将代码粘贴到SoapUI请求中,右键单击,重新格式化,然后查看SoapUI是否理解你的东西(如果你有专业版,请在表单和大纲视图中检查它)。如果看起来没问题,请将其关闭,看看是否得到与本地(soapUI)请求相同的响应。如果是这样,你很好走。但是,如果事情发生在错误的地方,命名空间被破坏,SoapUI无法呈现您的XML,那么您的代码中就有一些需要调整的地方。

+0

来自我的应用程序的XML和soapUI生成的XML之间唯一的区别是现在是信封前缀(SOAP-ENV vs soapenv),但是在这两种情况下,该前缀的URI是相同的。基于我读的前缀应该是不相干的,只要URI是一样的呢? – Less

+0

正确。只要前缀引用相同的URI,你就很好。 –