2011-08-22 87 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,你就很好。 –