Binu John's Weblog
JAX-WS: Capturing SOAP messages at the client side
One of the usual steps involved in the debugging of Web Services applications is to inspect the request and response SOAP messages. An easy way to do this is to use a proxy that sits between the client and the server. tcpmon, the TCP connection monitoring tool is the one that I use.
However, in certain situations, you may want to capture and log the SOAP message within the client process itself. Recently I had to deal with such a requirement for JAX-WS 2.0 and it turned out that it was quite easy to do this using the Handler framework. I added a logging handler to capture the request and response messages. The code snippet is given below.
|
import javax.xml.ws.BindingProvider; import javax.xml.ws.Binding; .... TestServicePortType proxy = new TestService().getTestServicePort(); BindingProvider bp = (BindingProvider) proxy; bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, urlStr); Binding binding = bp.getBinding(); // Add the logging handler List if (handlerList == null) handlerList = new ArrayList LoggingHandler loggingHandler = new LoggingHandler(...); handlerList.add(loggingHandler); binding.setHandlerChain(handlerList); .... // Invoking a method will activate the handler. proxy.someMethod(...); .... // Remove the logging handler if done with it. List if (handlerList != null && loggingHandler != null) handlerList.remove(loggingHandler); |
|
public class LoggingHandler implements SOAPHandler<SOAPMessageContext> { // Initialize OtputStream (fos) etc. ... public boolean handleMessage (SOAPMessageContext c) { SOAPMessage msg = c.getMessage(); boolean request = ((Boolean) c.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue(); try { if (request) { // This is a request message. // Write the message to the output stream msg.writeTo (fos); } else { // This is the response message msg.writeTo (fos); } } catch (Exception e) { ... } return true; } public boolean handleFault (SOAPMessageContext c) { SOAPMessage msg = c.getMessage(); try { msg.writeTo (fos); } catch (Exception e) {...} return true; } public void close (MessageContext c) { ... } public Set // Not required for logging return null; } } |
There is another implementation specific way of doing this - using the _setTransportFactory method. The handler approach is the more preferable option since it does not have any implementation dependencies.
Posted at 03:29PM Mar 08, 2006 by binu in Sun |