javaweb-servicesjax-ws

Tracing XML request/responses with JAX-WS


Is there an easy way (aka: not using a proxy) to get access to the raw request/response XML for a webservice published with JAX-WS reference implementation (the one included in JDK 1.5 and better) ? Being able to do that via code is what I need to do. Just having it logged to a file by clever logging configurations would be nice but enough.

I know that other more complex and complete frameworks exist that might do that, but I would like to keep it as simple as possible and axis, cxf, etc all add considerable overhead that I want to avoid.

Thanks!


Solution

  • Here is the solution in raw code (put together thanks to stjohnroe and Shamik):

    Endpoint ep = Endpoint.create(new WebserviceImpl());
    List<Handler> handlerChain = ep.getBinding().getHandlerChain();
    handlerChain.add(new SOAPLoggingHandler());
    ep.getBinding().setHandlerChain(handlerChain);
    ep.publish(publishURL);
    

    Where SOAPLoggingHandler is (ripped from linked examples):

    package com.myfirm.util.logging.ws;
    
    import java.io.PrintStream;
    import java.util.Map;
    import java.util.Set;
    
    import javax.xml.namespace.QName;
    import javax.xml.soap.SOAPMessage;
    import javax.xml.ws.handler.MessageContext;
    import javax.xml.ws.handler.soap.SOAPHandler;
    import javax.xml.ws.handler.soap.SOAPMessageContext;
    
    /*
     * This simple SOAPHandler will output the contents of incoming
     * and outgoing messages.
     */
    public class SOAPLoggingHandler implements SOAPHandler<SOAPMessageContext> {
    
        // change this to redirect output if desired
        private static PrintStream out = System.out;
    
        public Set<QName> getHeaders() {
            return null;
        }
    
        public boolean handleMessage(SOAPMessageContext smc) {
            logToSystemOut(smc);
            return true;
        }
    
        public boolean handleFault(SOAPMessageContext smc) {
            logToSystemOut(smc);
            return true;
        }
    
        // nothing to clean up
        public void close(MessageContext messageContext) {
        }
    
        /*
         * Check the MESSAGE_OUTBOUND_PROPERTY in the context
         * to see if this is an outgoing or incoming message.
         * Write a brief message to the print stream and
         * output the message. The writeTo() method can throw
         * SOAPException or IOException
         */
        private void logToSystemOut(SOAPMessageContext smc) {
            Boolean outboundProperty = (Boolean)
                smc.get (MessageContext.MESSAGE_OUTBOUND_PROPERTY);
    
            if (outboundProperty.booleanValue()) {
                out.println("\nOutbound message:");
            } else {
                out.println("\nInbound message:");
            }
    
            SOAPMessage message = smc.getMessage();
            try {
                message.writeTo(out);
                out.println("");   // just to add a newline
            } catch (Exception e) {
                out.println("Exception in handler: " + e);
            }
        }
    }