Necessidade de ver mensagens SOAP para o cliente falar com o serviço web externo - como? (Eclipse / Netbeans / IDEA ok)

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

Pergunta

Eu tenho uma situação onde eu tenho que escrever um cliente em Java contra um muito exigente serviço web externo (através de https) e eu posso falar com o serviço web através do Web Services Explorer no Eclipse Java EE.

Infelizmente eu não posso obter o cliente a pedir corretamente, então eu realmente gostaria de ver as mensagens SOAP indo e voltando. Sendo novo para serviços web isso é um pouco de uma selva. Estou muito familiarizados com o Eclipse, e ter passado algum tempo com o NetBeans e IntelliJ.

Eu realmente, realmente preferem usar a pilha de Metro, pois permite que este seja executado em um estoque Java 6, e o tamanho importa implantação. Existe uma maneira simples de fazer log Metro que faz, ou torná-lo falar através dos monitores TCP / IP em Eclipse e NetBeans? A documentação Metro parece estar destinada, sobretudo, ao autor do serviço web e não o cliente, então eu poderia facilmente ter perdido.

Todas as sugestões para uma configuração de dizer "Aqui está o WSDL - gerar me um cliente onde posso ver o tráfego"

?
Foi útil?

Solução 3

Foi útil activar o registo com

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

na configuração de lançamento do Eclipse.

Outras dicas

Basta colocar um proxy ou um monitor tcp "no meio" e você verá a mensagem.

Eu tenho usado tcpmon para uma tarefa similar.

Aqui está outra maneira de observar mensagens SOAP:

Supondo gerados classes de cliente parece com:

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

}

Agora, mediante a execução de código a seguir:

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

wsClient deve retornar instância que é tanto instância de RetrieveMyObjects & javax.xml.ws.BindingProvider interfaces. Não é indicado em qualquer lugar na superfície do JAX-WS, mas parece que um monte de código é baseado no fato. Pode-se re-assegurar-lhe \-se por executar 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");
}

Agora, quando temos certeza de que retrieveMyObjectsPort é instância de javax.xml.ws.BindingProvider podemos ativar o registro SOAPMessage invocando seguinte método em cada interface de porta de serviço web desejado:

/**
 * 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 isso ajude

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top