Necesidad de ver los mensajes SOAP para hablar con el cliente del servicio web externo - cómo? (Eclipse ok / Netbeans / IDEA)

StackOverflow https://stackoverflow.com/questions/2221488

Pregunta

Tengo una situación en la que tengo que escribir un cliente en Java contra de un servicio web externo muy exigente (a través de HTTPS) y puedo hablar con el servicio web a través del Explorador de servicios web en Eclipse Java EE.

Desafortunadamente no puedo conseguir que el cliente pida propiamente Realmente me gustaría ver los mensajes SOAP que van y vienen. Al ser nuevo en servicios web esto es un poco de una jungla. Estoy muy familiarizado con Eclipse, y he pasado algún tiempo con Netbeans y IntelliJ.

Me realmente, realmente prefiero usar la pila de metro, ya que permite que este se ejecute en un archivo Java 6, y el tamaño es importante despliegue. ¿Hay una manera simple de hacer log metro lo que hace, o hacer que hablar a través de los monitores de TCP / IP en Eclipse y Netbeans? La documentación de metro parece estar dirigida principalmente a la autora servicio web y no el cliente, por lo que podría fácilmente haber pasado por alto.

¿Alguna sugerencia para una configuración diciendo "Aquí está el WSDL - Me generar un cliente donde puedo ver el tráfico"?

¿Fue útil?

Solución 3

Fue muy útil para activar el registro con

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

en la configuración de lanzamiento de Eclipse.

Otros consejos

Sólo hay que poner un proxy o un monitor TCP "en el medio" y verá el mensaje.

He estado usando tcpmon para una tarea similar.

Esta es otra manera de observar los mensajes SOAP:

Suponiendo clases de cliente generados se parece a:

// 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();

}

Ahora, al ejecutar código siguiente:

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

wsClient debe devolver instancia que es a la vez ejemplo de interfaces RetrieveMyObjects y javax.xml.ws.BindingProvider. No se dice en cualquier lugar de la superficie de JAX-WS, pero parece que una gran cantidad de código se basa en ese hecho. Uno puede él volver a asegurar a \ a sí misma mediante la ejecución de algo como:

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");
}

Ahora, cuando estamos seguros de que es retrieveMyObjectsPort instancia de javax.xml.ws.BindingProvider podemos habilitar el registro SOAPMessage invocando siguiente método en cada interfaz de puerto de servicio web deseada:

/**
 * 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);

Espero que esto ayude

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top