Necessidade de ver mensagens SOAP para o cliente falar com o serviço web externo - como? (Eclipse / Netbeans / IDEA ok)
-
19-09-2019 - |
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"
?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