Нужно видеть сообщения SOAP для клиента, разговаривающего с внешним веб-сервисом - как? (Eclipse / Netbeans / IDEA в порядке) - PullRequest
1 голос
/ 08 февраля 2010

У меня есть ситуация, когда мне приходится писать клиент на Java для очень требовательного внешнего веб-сервиса (через https), и я могу общаться с веб-сервисом через проводник веб-сервисов в Eclipse Java EE.

К сожалению, я не могу заставить клиента правильно спрашивать, поэтому мне бы очень хотелось, чтобы сообщения SOAP проходили взад и вперед. Быть новичком в веб-сервисах - это что-то вроде джунглей. Я очень хорошо знаком с Eclipse и провел некоторое время с Netbeans и IntelliJ.

Я бы действительно предпочел использовать стек Metro, поскольку он позволяет работать на стандартной Java 6, и размер развертывания имеет значение. Есть ли простой способ заставить журнал Metro делать то, что он делает, или заставить его общаться через мониторы TCP / IP в Eclipse и Netbeans? Документация Metro, по-видимому, в первую очередь предназначена для автора веб-службы, а не для клиента, поэтому я мог бы легко ее пропустить.

Любые предложения по настройке, говорящие "Вот WSDL - сгенерируйте мне клиента, где я могу видеть трафик"?

Ответы [ 3 ]

2 голосов
/ 19 марта 2012

Вот еще один способ наблюдать сообщения 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();

wsClient должен возвращать экземпляр, который является экземпляром интерфейсов RetrieveMyObjects и 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 является экземпляром 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);

Надеюсь, это поможет

2 голосов
/ 08 февраля 2010

Просто поставьте прокси или tcp монитор "посередине", и вы увидите сообщение.

Я использовал tcpmon для аналогичной задачи.

1 голос
/ 22 февраля 2010

Было полезно включить ведение журнала с помощью

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

в конфигурации запуска Eclipse.

...