2013-05-20 79 views
0

我在這裏發現了一些關於如何從JAX-WS客戶端獲取XML響應的線程。就我而言,客戶端是通過Oracle的JDeveloper產品從WSDL生成的,並且將調用用.NET編寫的Document/Literal服務端點。我想要做的是從調用客戶端調用獲取XML響應,而不是從處理程序中獲取。如何從JAX-WS客戶端獲取XML響應體?

,我看到了這個問題,最近的主線是: http://www.coderanch.com/t/453537/Web-Services/java/capture-SoapRequest-xml-SoapResponse-xml

我不認爲我想生成一個調度呼叫,因爲對SOAP包的終端的XML架構是相當複雜的,和自動代理使通話變得微不足道。除非有其他方法來填充生成的bean,然後調用一些簡單生成XML的方法,然後我才能進行調用?

private void storeSOAPMessageXml(SOAPMessageContext messageContext) { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    SOAPMessage soapMessage = messageContext.getMessage(); 
    try { 
     soapMessage.writeTo(baos); 
     String responseXml = baos.toString(); 
     log.debug("Response: " + responseXml); 
     PaymentGatewayXMLThreadLocal.set(responseXml); 
    } catch (SOAPException e) { 
     log.error("Unable to retrieve SOAP Response message.", e); 
    } catch (IOException e) { 
     log.error("Unable to retrieve SOAP Response message.", e); 
    } 
} 

我的想法是將響應保存到處理程序中的ThreadLocal中,然後在調用之後讀取它。這是否合理?因此,處理程序中的handleMessage和handleFault上面的代碼後,客戶端調用代碼調用該方法:

@Override  
public String getSOAPResponseXML(Object clientstub) { 
    String returnValue = PaymentGatewayXMLThreadLocal.get(); 
    return returnValue; 
} // getSOAPResponseXML 

看來有可能是畢竟另一種方式。在閱讀jax-ws-handlers之後,我看到該處理程序可以引入Application範圍變量。我改變了處理程序來做到這一點:

private void storeSOAPMessageXml(SOAPMessageContext messageContext) { 
String xml = getSOAPMessageXml(messageContext); 
// YourPayXMLThreadLocal.set(xml); 
// put it into the messageContext as well, but change scope 
// default of handler Scope, and client can't read it from responsecontext! 
messageContext.put(SOAP_RESPONSE_XML, xml); 
messageContext.setScope(SOAP_RESPONSE_XML, MessageContext.Scope.APPLICATION); 
} // storeSOAPMessageXml 

客戶端只是讀取它是這樣的:

@Override  
public String getSOAPResponseXML(Object clientstub) { 
    String returnValue = null; 
    // works (assuming a threadlocal is ok) 
    // returnValue = YourPayXMLThreadLocal.get(); 

    BindingProvider bindingProvider = (BindingProvider) clientstub; 
    // Thought this would work, but it doesn't - it returns null.   
    // Map<String, Object> requestContext = bindingProvider.getRequestContext(); 
    // String returnValue = (String) requestContext.get(JaxWsClientResponseXmlHandler.SOAP_RESPONSE_XML); 

    // this works!! 
    Map<String, Object> responseContext = bindingProvider.getResponseContext(); 
    System.out.println("has key? " + responseContext.containsKey(JaxWsClientResponseXmlHandler.SOAP_RESPONSE_XML));   
    returnValue = (String) responseContext.get(JaxWsClientResponseXmlHandler.SOAP_RESPONSE_XML); 
    return returnValue; 
} // getSOAPResponseXML 

回答

0

如果你只是想看看的要求,就可以使用系統屬性

-Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true 

如果你真的想東西與請求,然後處理程序似乎是自然的解決方案。也許使用請求上下文將值傳遞給處理程序?在客戶端:

((BindingProvider) port).getRequestContext().put("KEY", "VALUE"); 

在處理程序:

String value = (String) messageContext.get("KEY"); 
+1

我不只是想看到它,我想根據客戶端已知的事務ID#將其登錄到數據庫。我創建此日誌條目PRIOR發送請求。處理程序不會知道這個事務ID#(它不是請求的一部分 - 這是我的日誌)。我想知道來自調用的結果SOAP Response。在apache Axis中,我回應了另一個therad [here](http://stackoverflow.com/questions/3842900/is-it-possible-to-access-the-raw-soa-xml-message-in-a-jax -rpc-Java的客戶機/ 16572303#16572303)。我想到一個更新的WS客戶端堆棧會使這更容易。所以threadlocal可以嗎? – user1955401

+0

jax-ws客戶端將soap響應解組爲來自付款網關的強類型對象。不幸的是,我們遇到了過去的情況,我們得到的未公開的錯誤代碼和字符串比預期/記錄的時間長。然後,我們的例程簡單地堅持迴應將失敗。那時,故障安全響應列(clob)也被添加到日誌中。如果我走你的路線,我的處理程序必須能夠堅持這個響應,因爲當我試圖將KEY/VALUE對放入處理程序並在客戶端讀取時它是空的。如果有幫助,我也使用MyBatis/Spring。 – user1955401

0

不幸的是,在發送之前並沒有使用消息處理程序來獲取XML的唯一方法是馬歇爾它你的自我(見JAXB)。這將爲您提供數據的XML表示,但它可能不會與發送給WS的消息完全相同。使用命名空間的方式可能會產生差異,但最重要的是,您不會獲得整個SOAP信封,只是您選擇編組頭的XML數據。

+0

我看到一個響應[這裏](http://stackoverflow.com/questions/12013476/how-can-i-pass-data-back-from-a-soap-handler-to-a-webservice-client?rq = 1)。在發送它之前,我絕對不想要xml **。我想要回應。 SOAPFaults和其他錯誤阻止WS客戶端解組到Strongly類型的Java對象。所以,我想要有XML **響應**有效載荷。這回到我的原始問題:是否有任何理由我不能把它放在處理程序中的ThreadLocal中以從客戶端檢索?再次感謝所有的幫助。 – user1955401

相關問題