Search code examples
web-servicessoapjax-ws

Logging soap requests and responses body only Jax WS


I am using JAX-WS for the webservices in my project. I want to log every request and response for these webservices. For the time being, I am successfully logging every request/response, however I wish to remove the header part for security reasons and keep the body, I am using in my SOAPHandler this method to write in the application log:

private void logToSystemOut(SOAPMessageContext smc) {
        Logger logger = Logger.getLogger(LogHandler.class);
        Boolean outboundProperty = (Boolean) smc
                .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (outboundProperty.booleanValue()) {
            logger.info("Outbound message:");
        } else {
            logger.info("Inbound message:");
        }

        SOAPMessage message = smc.getMessage();
        try {
            Source source = message.getSOAPPart().getContent();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            Transformer transformer = TransformerFactory.newInstance()
                    .newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty(
                    "{http://xml.apache.org/xslt}indent-amount", "3"); 
            transformer.transform(source, new StreamResult(baos));
            logger.info(baos.toString());
        } catch (Exception e) {
            logger.warn("Exception in handler: " + e);
        }
    }

This of course logs every request/response without distinguishing the headers and bodies. I tried using the message.getSOAPBody(), but it keeps logging null.

All recommendation are welcome.

PS: This is the return for message.getSOAPBody() is [S:Body: null]


Solution

  • I have successfully solved the problem used the detachnode method for the SOAP header as follows:

     message.getSOAPHeader().detachNode();
    

    Here's a code sample of how the code becomes (notice how I test on whether the soapHeader is non-null, because otherwise it'd throw a null pointer exception):

        private void logToSystemOut(SOAPMessageContext smc) {
        Logger logger = Logger.getLogger(LogHandler.class);
        Boolean outboundProperty = (Boolean) smc
                .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (outboundProperty.booleanValue()) {
            logger.info("Outbound message:");
        } else {
            logger.info("Inbound message:");
        }
    
        SOAPMessage message = smc.getMessage();
        try {
            if(message.getSOAPHeader()!=null)
            message.getSOAPHeader().detachNode();
            Source source = message.getSOAPPart().getContent();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            Transformer transformer = TransformerFactory.newInstance().newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "3"); 
            transformer.transform(source, new StreamResult(baos));
            logger.info(baos.toString());
        } catch (Exception e) {
            logger.warn("Exception in handler: " + e);
        }
    }}