1

我有一种情况,我必须针对非常挑剔的外部 Web 服务(通过 https)编写 Java 客户端,并且我可以通过 Eclipse Java EE 中的 Web 服务资源管理器与 Web 服务对话。

不幸的是,我无法让客户正确询问,所以我真的很想看到 SOAP 消息来回传递。作为 Web 服务的新手,这有点像丛林。我对 Eclipse 非常熟悉,并且在 Netbeans 和 IntelliJ 上花了一些时间。

我真的非常喜欢使用 Metro 堆栈,因为它允许它在 Java 6 上运行,并且部署大小很重要。有没有一种简单的方法可以让 Metro 记录它所做的事情,或者让它通过 Eclipse 和 Netbeans 中的 TCP/IP 监视器进行通信?Metro 文档似乎主要针对 Web 服务作者而不是客户端,所以我可能很容易错过它。

对于设置说“这里是 WSDL - 为我生成一个可以看到流量的客户端”的设置有什么建议吗?

4

3 回答 3

2

只需在“中间”放置一个代理或 tcp 监视器,您就会看到该消息。

我一直在使用tcpmon来完成类似的任务。

于 2010-02-08T13:07:48.207 回答
2

这是观察 SOAP 消息的另一种方法:

假设生成的客户端类如下所示:

// generated service class
public class MyWebServiceClient extends javax.xml.ws.Service {
    // ...
    private final QName portName = "...";
    // ...
    public RetrieveMyObjects getRetrieveMyObjects() {
        return super.getPort(portName, RetrieveMyObject.class);
    }
    // ...
}

// generated port interface
// annotations here
public interface RetrieveMyObjects {

    // annotations here
    List<MyObject> getAll();

}

现在,在执行以下代码时:

MyWebServiceClient wsClient = new MyWebServiceClient("wsdl/location/url/here.wsdl");
RetrieveMyObjectsPort retrieveMyObjectsPort = wsClient.getRetrieveMyObjects();

wsClientRetrieveMyObjects应该返回既是&javax.xml.ws.BindingProvider接口的实例的实例。JAX-WS 表面上没有任何地方说明,但似乎很多代码都是基于这个事实。可以通过执行以下操作来重新向他/她自己保证:

if(!(retrieveMyObjectsPort instanceof javax.xml.ws.BindingProvider)) {
    throw new RuntimeException("retrieveMyObjectsPort is not instance of " + BindingProvider.class + ". Redirect following as well as authentication is not possible");
}

现在,当我们确定这retrieveMyObjectsPort是一个实例时,我们可以通过在每个所需的 Web 服务端口接口上调用以下方法javax.xml.ws.BindingProvider来启用日志记录:SOAPMessage

/**
 * Enables logging of send and received SOAP messages on the specified {@link BindingProvider}s
 */
private static void enableSoapMessageLogging(final Logger logger, final BindingProvider... bindingProviders) {
    for(final BindingProvider bindingProvider : bindingProviders) {
        final List<Handler> handlerChain = bindingProvider.getBinding().getHandlerChain();
        handlerChain.add(new SOAPHandler<SOAPMessageContext>() {
            @Override
            public boolean handleMessage(final SOAPMessageContext context) {
                try {
                    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    context.getMessage().writeTo(baos);
                    logger.trace(new String(baos.toByteArray()));
                } catch(final Exception e) {
                    logger.error("", e);
                }
                return true;
            }

            @Override
            public boolean handleFault(final SOAPMessageContext context) {
                return true;
            }

            @Override
            public void close(final MessageContext context) {
            }

            @Override
            public Set<QName> getHeaders() {
                return null;
            }
        });
        bindingProvider.getBinding().setHandlerChain(handlerChain);
    }
}

// and somewhere at the beginning of application ...
enableSoapMessageLogging(logger, (BindingProvider) retrieveMyObjectsPort);

希望这可以帮助

于 2012-03-19T08:30:30.367 回答
1

打开日志记录很有帮助

-Dcom.sun.xml.ws.assembler.client=true

在 Eclipse 启动配置中。

于 2010-02-22T18:43:20.560 回答