When working with SOAP web services in a Spring Boot application, it’s often necessary to log incoming and outgoing SOAP messages for debugging, auditing, or monitoring purposes. Unlike REST APIs, where logging can be handled easily with filters and interceptors, SOAP requires a specialized approach.

Why Log SOAP Messages?#

  • Debugging: Helps developers diagnose issues by capturing full request and response messages.
  • Auditing: Ensures compliance by keeping a record of exchanged messages.
  • Monitoring: Allows tracking of service interactions in production.

Implementing a SOAP Logging Handler#

Spring Boot provides integration with SOAP web services using JAX-WS. To log SOAP requests and responses, we can implement a custom SOAPHandler. Here’s a simple SoapLoggingHandler that captures both inbound (responses) and outbound (requests) SOAP messages:

public class SoapLoggingHandler implements SOAPHandler<SOAPMessageContext> {

    private static final Logger LOGGER = LoggerFactory.getLogger(SoapLoggingHandler.class);

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        boolean isOutbound = (boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

        SOAPMessage message = context.getMessage();
        try {
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            message.writeTo(outputStream);
            String soapXml = outputStream.toString(String.valueOf(StandardCharsets.UTF_8));
            LOGGER.info(isOutbound ? "Outbound SOAP Request: {}" : "Inbound SOAP Response: {}", soapXml);
        } catch (IOException | SOAPException e) {
            LOGGER.error("Exception, ", e);
        }
        return true;
    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {
        return handleMessage(context);
    }

    @Override
    public void close(MessageContext context) { /* No needed */ }

    @Override
    public Set<QName> getHeaders() {
        return Collections.emptySet();
    }
}

How It Works#

  • The handleMessage method determines whether the message is an outbound request or an inbound response.
  • The SOAP message is written to a ByteArrayOutputStream to extract its XML content.
  • The extracted XML is logged using SLF4J.
  • The handleFault method ensures that SOAP faults are also logged.

Registering the Handler#

To activate this logging handler, register it in your HandlerResolver and bind it to your SOAP client or server.

  • For a SOAP Client

    If you’re using JaxWsProxyFactoryBean, you can register the handler like this:

    BindingProvider bindingProvider = (BindingProvider) soapDemoSoap;
    List<Handler> handlerChain = bindingProvider.getBinding().getHandlerChain();
    handlerChain.add(LOGGING_HANDLER);
    bindingProvider.getBinding().setHandlerChain(handlerChain);
    
  • For a SOAP Server

    You can configure the handler in your @WebService annotated class.

Example Log Outputs#

Below are sample logs that demonstrate how inbound and outbound SOAP messages are logged. These logs help with debugging and monitoring SOAP requests and responses efficiently.

27-03-2025 00:10:49.272 | INFO | [http-8080] | 
com.fati.soaploggingjava.SoapLoggingHandler | Outbound SOAP Request: 
<S:Envelope 
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/><S:Body><ns2:LookupCity 
xmlns:ns2="http://tempuri.org" xmlns:ns3="http://tempuri.org/QueryByName_DataSet" 
xmlns:ns4="http://tempuri.org/ByNameDataSet" 
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<ns2:zip>11368</ns2:zip></ns2:LookupCity></S:Body></S:Envelope>
27-03-2025 00:10:50.047 | INFO | [http-8080] | 
com.fati.soaploggingjava.SoapLoggingHandler | Inbound SOAP Response: 
<SOAP-ENV:Envelope 
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:s="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Header/><SOAP-ENV:Body><LookupCityResponse xmlns="http://tempuri.org">
<LookupCityResult><City>Corona</City><State>NY</State><Zip>11368</Zip>
</LookupCityResult></LookupCityResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>

Conclusion#

Logging SOAP messages in a Spring Boot application is essential for debugging, auditing, and monitoring. By implementing a custom SOAPHandler, we can easily capture and log SOAP requests and responses. This simple yet effective solution helps in maintaining transparency and troubleshooting issues effectively.

If you’re working with SOAP in Spring Boot, integrating this logging mechanism can save you valuable debugging time and improve your application’s observability.

The source code for this post is available in my GitHub repository. Feel free to explore and contribute.

Thank you for reading, I hope this post helps you effectively log SOAP messages in your applications. If you have any questions or suggestions, feel free to share them in the comments. 🚀