3

JAX-WS クライアントから XML 応答を取得する方法について、ここでいくつかのスレッドを読んでいることがわかりました。私の場合、クライアントは Oracle の JDeveloper 製品を介して WSDL から生成され、.NET で記述された Document/Literal サービス エンドポイントを呼び出します。私がやりたいことは、ハンドラー内からではなく、呼び出し元のクライアントからの呼び出しから XML 応答を取得することです。

この問題に最も近いスレッドは次のとおりです: http://www.coderanch.com/t/453537/Web-Services/java/capture-SoapRequest-xml-SoapResponse-xml

SOAP パケットのエンドポイントの XML スキーマはかなり複雑であり、自動プロキシによって呼び出しが簡単になるため、Dispatch 呼び出しを生成する必要はないと思います。生成された 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
4

2 に答える 2

1

リクエストを表示したいだけの場合は、システム プロパティを使用できます。

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

実際にリクエストで何かをしたい場合は、ハンドラーが自然な解決策のようです。おそらく、要求コンテキストを使用してハンドラーに値を渡しますか? クライアントで:

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

ハンドラーで:

String value = (String) messageContext.get("KEY");
于 2013-05-20T15:15:45.380 に答える