Spring WS Intercept Request Response Soap Messages

In the previous tutorial we saw how to produce and consume a Spring WS Soap Service. This time, we show you how to use Spring Ws Endpoint Interceptors. These endpoint interceptors can be used for intercepting response and or request soap messages, intercepting exceptions and execute some code after completion. We can register interceptors for a specific endpoint only or a global interceptor. We use Java Configuration to register our custom interception and spring boot to bootstrap the application.

Spring WS Intercept Soap Messages

Global Interceptor

Interceptors must implement the EndpointInterceptor interface. This interface defines 4 methods.

  • handleRequest this method is invoked before the endpoint and returns a boolean value. You can use this method to interrupt or continue the processing of the invocation chain. When this method returns true, the endpoint execution chain will continue. When it returns false, the MessageDispatcher interrupts the invocation chain. Which means that it will not continue to invoke interceptors or endpoints in the chain.
  • handleResponse and handleFault are executed after the invocation of the endpoint and are used for post-processing. These methods all return a boolean when they return false, the response will not be sent back to the client.
  • afterCompletion is executed after the endpoint is executed and does not return anything because it’s the last step in the chain.
package com.memorynotfound.server;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.EndpointInterceptor;

@Component
public class GlobalEndpointInterceptor implements EndpointInterceptor {

    private static final Log LOG = LogFactory.getLog(GlobalEndpointInterceptor.class);

    @Override
    public boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {
        LOG.info("Global Request Handling");
        return true;
    }

    @Override
    public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
        LOG.info("Global Response Handling");
        return true;
    }

    @Override
    public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
        LOG.info("Global Exception Handling");
        return true;
    }

    @Override
    public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) throws Exception {
        LOG.info("Execute Code After Completion");
    }
}

Endpoint Interceptor

We can also bind an interceptor to a specific endpoint. Here is the custom interceptor that we are going to bind to the endpoint. Note that this class also implements the EndpointInterceptor. The binding happens in the Configuration.

package com.memorynotfound.server;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.EndpointInterceptor;

@Component
public class CustomEndpointInterceptor implements EndpointInterceptor {

    private static final Log LOG = LogFactory.getLog(CustomEndpointInterceptor.class);

    @Override
    public boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {
        LOG.info("Endpoint Request Handling");
        return true;
    }

    @Override
    public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
        LOG.info("Endpoint Response Handling");
        return true;
    }

    @Override
    public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
        LOG.info("Endpoint Exception Handling");
        return true;
    }

    @Override
    public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) throws Exception {
        LOG.info("Execute code after completion");
    }
}

Configure Interceptor using Spring Java Configuration

Now we have written our CustomEndpointInterceptor we need to tell Spring WS to use it. We do this by overriding the addInterceptors method of the WsConfigurerAdapter. We define a global interceptor by just adding it to the interceptors list. For an endpoint specific interceptor we must use the PayloadRootSmartSoapEndpointInterceptor class which takes a delegate interceptor, a namespace and a localPart as arguments. The interceptor uses the namespace and local part to map the interceptor to the endpoint.

package com.memorynotfound.server;

import org.springframework.context.annotation.Configuration;
import org.springframework.ws.config.annotation.EnableWs;
import org.springframework.ws.config.annotation.WsConfigurerAdapter;
import org.springframework.ws.server.EndpointInterceptor;
...

@EnableWs
@Configuration
public class SoapServerConfig extends WsConfigurerAdapter {

    @Override
    public void addInterceptors(List<EndpointInterceptor> interceptors) {

        // register global interceptor
        interceptors.add(new CustomEndpointInterceptor());

        // register endpoint specific interceptor
        interceptors.add(new PayloadRootSmartSoapEndpointInterceptor(
                new CustomEndpointInterceptor(),
                BeerEndpoint.NAMESPACE,
                BeerEndpoint.BEER_REQUEST_LOCAL_PART));
    }

    ...

}

References

Download

You may also like...