使用JAX-WS在客户端跟踪SOAP请求/响应

18
我正在使用JAX-WS参考实现(2.1.7)并希望在客户端跟踪SOAP请求/响应。实际上,我需要在接收响应时检查一些HTTP标头。
根据之前的这些问题(Tracing XML request/responses with JAX-WSJava JAX-WS web-service client: how log request & response xml?),我创建了自己的处理程序以记录发送请求和接收响应的日志:
public class SHandler implements SOAPHandler<SOAPMessageContext>
{

  private static final Logger log = Logger.getLogger(SHandler.class);

  @Nullable
  @Override
  public Set<QName> getHeaders()
  {    
    log.debug(">>>>>>>>>>> GetHeaders");
    return null;    
  }

  @Override
  public boolean handleMessage(SOAPMessageContext soapMessageContext)
  {
    log.debug(">>>>>>>>>>> HandleMessage");
    return true;
  }

  @Override
  public boolean handleFault(SOAPMessageContext soapMessageContext)
  {
    log.debug(">>>>>>>>>>> HandleFault");
    return true;
  }

  @Override
  public void close(MessageContext messageContext)
  {
    log.debug(">>>>>>>>>>> Close");    
  }
}

我在服务初始化期间将处理程序添加到处理程序链中:

@WebServiceClient(name = "MyService", targetNamespace = "http://www.whatever.com/", wsdlLocation = "file:/path/to/wsdl")
public class MyService extends Service
{

    public MyService(URL wsdlLocation) {
        super(...);
        initializeBinding();
    }

    @WebEndpoint(name = "MyOperation")
    public MyPort getMyPort() {
        return super.getPort(new QName("http://www.whatever.com/", "MyPort"), MyPort.class);
    }

    private void initializeBinding() {        
        MyPort port = getMyPort();
        BindingProvider bindingProvider = ((BindingProvider) port);
        List handlerChain = bindingProvider.getBinding().getHandlerChain();
        handlerChain.add(new SHandler());
        bindingProvider.getBinding().setHandlerChain(handlerChain);        
    }

    ...

}
问题在于在客户端上根本不起作用。 当我发送请求并接收响应时,我看不到任何日志,并且我的处理程序从未执行。请注意,对于此问题没有特定的WSDL,因为我在MDA平台上工作,该平台可以从任何WSDL生成客户端/服务器构件。此外,我无法在配置级别上执行此操作,因为所有内容都是生成的,因此我只能以编程方式执行它(我一直在搜索这个问题,但我找到的所有解决方案要么与原始帖子中的解决方案相同,要么使用handler-chain.xml配置文件)。我有什么遗漏吗?还有其他方法可以做到这一点吗?预先感谢。
3个回答

23

如果你只想查看运行的SOAP消息,请使用以下命令:

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

虚拟机参数。


我已经在使用该SP将请求和响应转储到日志中,但我需要根据消息、标头等执行一些操作。例如,如果我收到一个500(内部服务器错误)的响应,则抛出异常。我的处理程序只是一个示例。 - Denian
1
据我理解,这总是会输出到 System.out(或 .err)而不是日志文件。 - Thorbjørn Ravn Andersen
这对我似乎没有影响。我猜测正确的标志可能因使用的版本而异(而我不知道我正在使用哪个版本)。 - Hakanai
1
从Java 1.7开始,这似乎已经改变了。请参见https://dev59.com/IHXYa4cB1Zd3GeqP_-6D - sleske

6

为什么不使用@HandlerChain(file = "....")注释?

在我看来,您不能混合基于构造函数和注释的配置,因为在部署时Web服务初始化和创建服务类的新实例是在完全不同的上下文中执行的。


抱歉在我的问题中忘记提到,我已经检查过这个解决方案,但仍需要一个XML的引用。 - Denian
顺便说一句,我认为你在构造函数中这样做是正确的。再次查看HandlerChain,我发现了这个链接:https://www.ibm.com/developerworks/mydeveloperworks/blogs/amsurana/entry/jax_ws_handlers_part_3_of_3 看起来可以使用HandlerResolver来实现。我明天会尝试一下。 - Denian
你可以尝试使用HandlerResolver接口,类似于http://www.javaworld.com/javaworld/jw-02-2007/jw-02-handler.html?page=3的方式。 - andbi

1

有两个工具可以帮助你解决这个问题:

这两个工具都提供了代理模式,可以拦截、记录和转发请求和响应。


1
好的,正如我所说,根据响应,我需要在应用程序本身执行一些操作,因此我不能使用外部工具。 - Denian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接