【问题标题】:How to get the XML response body back from a JAX-WS client?如何从 JAX-WS 客户端取回 XML 响应正文?
【发布时间】:2013-05-15 04:21:49
【问题描述】:

我在这里找到了许多关于如何从 JAX-WS 客户端检索 XML 响应的线程。在我的例子中,客户端是通过 Oracle 的 JDeveloper 产品从 WSDL 生成的,并将调用用 .NET 编写的 Document/Literal 服务端点。我想要做的是从调用客户端的调用中获取 XML 响应,而不是从处理程序内部。

我看到的最接近这个问题的线程是: http://www.coderanch.com/t/453537/Web-Services/java/capture-SoapRequest-xml-SoapResponse-xml

我认为我不想生成 Dispatch 调用,因为 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 中,然后在调用后读取它。这合理吗?所以handler在handleMessage和handleFault中做了上述代码后,客户端调用代码调用这个方法:

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

看来毕竟还有其他方法。在阅读jax-ws-handlers 之后,我看到处理程序可以引入一个应用程序范围的变量。我更改了处理程序来执行此操作:

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

【问题讨论】:

    标签: java xml jax-ws soaphandler


    【解决方案1】:

    如果只想看请求,可以使用系统属性

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

    如果您真的想对请求一些事情,那么处理程序似乎是自然的解决方案。也许使用请求上下文将值传递给处理程序?在客户端:

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

    在处理程序中:

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

    【讨论】:

    • 我不只是想看到它,我想根据客户端已知的事务 id# 将它记录到数据库中。我在发送请求之前创建了这个日志条目。处理程序不会知道此事务 id#(它不是请求的一部分 - 这是我的日志)。我想知道调用产生的 SOAP 响应。在 apache Axis 中,我回复了另一个 therad here。我认为更新的 WS 客户端堆栈会使这更容易。那么threadlocal可以吗?
    • jax-ws 客户端将soap响应解组为来自支付网关的强类型对象。不幸的是,过去我们遇到过未记录的错误代码和字符串长于预期/记录的情况。那么我们简单地坚持响应的例程就会失败。那时故障安全响应列 (clob) 也被添加到日志中。如果我走你的路线,我的处理程序必须能够持久保存这个响应,就像当我尝试将 KEY/VALUE 对放入处理程序并在客户端中读取它为空时一样。如果有帮助,我也会使用 MyBatis/Spring。
    【解决方案2】:

    不幸的是,在发送之前获取 XML 并且不使用消息处理程序的唯一方法是自己编组(请参阅 JAXB)。这将为您提供数据的 XML 表示,但它可能看起来与发送到 WS 的消息不完全相同。命名空间的使用方式可能会出现差异等,但最重要的是,您不会获得整个 SOAP 信封,只会获得您选择编组的标头的 XML 数据。

    【讨论】:

    • 我看到了here 对此的回复。我绝对不希望 xml before 发送它。我想要回应。 SOAPFaults 和其他错误会阻止 WS 客户端解组到强类型 Java 对象。所以,我想要 XML response 有效负载。这又回到了我最初的问题:有什么理由我不能把它放在处理程序的 ThreadLocal 中以从客户端检索?再次感谢您的所有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-25
    • 1970-01-01
    • 2012-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多