2011-06-28 64 views
1

我正在從WSDL創建Web服務客戶端。從WSDL開發Webservice客戶端時出現異常

一個典型的SOAP請求到服務看起來是這樣的

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:someGateway"> 
    <soapenv:Header/> 
    <soapenv:Body> 
     <urn:send>  
      <urn:message> 
       <urn:messageID>1001</urn:messageID> 
       <urn:messageBody> 
        <DataContainer> 
         SOME MORE ELEMENTS 
        </DataContainer> 
       </urn:messageBody> 
      </urn:message> 
     </urn:send> 
    </soapenv:Body> 
</soapenv:Envelope> 

我用JAX-WS生成服務文物和填充我的目標如下:

Message message = objectFactory.createMessage(); 
//Set message ID 
String messageID = "123456" 
message.setMessageID(messageID); 
//Set message Body 
MessageBody messageBody = objectFactory.createMessageMessageBody() 

的消息體對象有隻有1個方法messageBody.setAny(value)。但我需要在其中放置一個DataContainer元素。

我已經試過傳:

  1. org.w3c.dom.DocumentObject(我得到 「javax.xml.ws.soap.SOAPFaultException:無法處理請求」)probbaly因xml decleration。如通過JAXB從XSD(I得到 「[javax.xml.bind.JAXBException:類DataContainer或其任何超類的已知此上下文]」)生成
  2. DataContainer對象
  3. 的JAXBElement(我得到「[javax.xml.bind.JAXBException:類DataContainer不知道這個上下文]」)

我在做什麼錯?或者我需要做什麼才能在消息正文中獲得DataContainer

+0

確定WSDL是否正確? –

+0

是的,我已經使用SoapUI向服務發送類似的請求,並且它工作正常 – Maro

回答

1

正如您所提到的,您有messageBody.setAny(value)這意味着MessageBody的XSI:type已被設置爲anytype。這意味着你可以在那裏設置任何對象,JAXB應該能夠在由JAX-WS wsdl2java工具定義的上下文中編組它。從錯誤消息'無法在Conext中找到DataContainer',看起來您的DataContainer類不在同一個上下文中。

這是一個解決方法,你可以編組你的DataContainer對象到JAXBElement<String>(或者可能只是一個字符串,但我不確定這是否可行)對象,然後將其設置爲anyType。這樣你不會在上下文中得到Class,因爲String是基本的JAXB類型。

我不知道你是如何定義你的包結構,當你試圖使用點2或3,所以我在這裏採取野性刺。從錯誤消息看來,您分開生成的DataContainer類與Message及其子類不在同一個包中。嘗試將DataContainer及其關聯的類移至與Message類相同的包,並將兩個ObjectFactory類合併在一起。這應該允許JAXB在與Message相同的「上下文」中查找DataContainer。

當您發出實際的請求並且JAXB封送對象以創建請求(即JAX-WS在內部調用JAXB Marshelling服務)時,可能發生此錯誤。在這種情況下,當您生成客戶端時,JAXBContext被設置爲Message類所在的包。

這是一個簡單的教程,它處理JAXBContext封送和解組。 http://download.oracle.com/docs/cd/E17802_01/webservices/webservices/docs/1.6/tutorial/doc/JAXBUsing3.html

也按照this,你可以設置anyType爲org.w3c.dom.Element而不是org.w3c.dom。文檔

0

使用xs:任何未包含的XSD類型的祕密是@XmlSeeAlso。當你從xjc工具創建你的JAXB類時,你會得到一個定義@WebService方法的接口。該接口也將被客戶端和服務實現使用。如果你不改變,你最好在你的包擴展這個界面自動生成的Java文件,並添加@XmlSeeAlso({ExternalClassYouWantToReferTo.class})這個新的接口,例如:IWebServiceInterface

@WebService(name = "IExternalXmlBatchReceive", targetNamespace = "http://External.ServiceContract.BatchReceive") 
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE) 
@XmlSeeAlso({ 
    ObjectFactory.class, ExternalClassYouWantToReferTo.class 
}) 
public IWebServiceInterface extends InterfaceYourAutoCreationCode { 
@WebMethod(name=...) 
...... 
} 

你的所有Service@WebService從實施這個界面。

當客戶來電getPort方法,你應該通過新實現的接口像第二個參數:

IWebServiceInterface wi = service.getPort(YOUR_QNAME, IWebServiceInterface.class); 

getPort方法將考慮您傳遞的@XmlSeeAlso接口和初始化其內部JAXBContext中。

相關問題