Spring Controller start processing after response is sent

You can use an interceptor for that. The order of events for handling a request in Spring MVC is:

  • DispatcherServlet get a Request, Response pair and determines the handling
  • [optional] interceptors preHandle are called (with option to stop processing)
  • controller is called
  • [optional] interceptors postHandle are called
  • ViewResolver and view do the actual Response processing and send the response
  • [optional] interceptors afterCompletion are called

The above is over simplified and is just aimed at showing that interceptor afterCompletion methods are called after the response has been sent to client, with following signature :

void afterCompletion(HttpServletRequest request,
                     HttpServletResponse response,
                     Object handler,
                     Exception ex)
                     throws Exception

In that method, you can test the occurence of an exception and the correctness of the response (ex == null && response.getStatus() == HttpServletResponse.SC_OK) before starting your processing.


The HandlerInterceptor is the solution, but the code get a little bit more complex than expected.

Here's a code suggestion to make it simpler by putting the whole solution in a single class:

private static final ThreadLocal<Object> result = new ThreadLocal<Object>();

@RequestMapping("/mypath")
public Object execute() throws Exception {
    Object obj = new Object();
    result.set(obj); // Save the object to be used after response
    return obj;
}

@Bean
public MappedInterceptor interceptor() {
    return new MappedInterceptor(Arrays.array("/mypath"), new HandlerInterceptor() {
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            // Get the saved object
            Object results = result.get();

            // Clean for the next request
            result.set(null);

            // TODO Your code to be executed after response.
        }
    });
}

If your "after respond is sent" requirement is fulfilled with "after the view has been rendered" you may use an implementation of HandlerInterceptor. For an example cf. Spring 3 MVC Interceptor tutorial with example, triggering your job in afterCompletion.

If your job needs to be triggered "after it hit the wire", I'd like to know why.