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.