Spring MVC CallableProcessingInterceptor is registered in HandlerInterceptor#preHandle to intercept more deeply into async Callable life-cycle request.  package com.logicbig.example;
import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.async.CallableProcessingInterceptor; import java.time.LocalTime; import java.util.concurrent.Callable;
public class MyCallableProcessingInterceptor implements CallableProcessingInterceptor { @Override public <T> void beforeConcurrentHandling( NativeWebRequest request, Callable<T> task) throws Exception { log("beforeConcurrentHandling called"); }
@Override public <T> void preProcess( NativeWebRequest request, Callable<T> task) throws Exception {
log("preProcess called."); }
@Override public <T> void postProcess(NativeWebRequest request, Callable<T> task, Object concurrentResult) throws Exception { log("postProcess called"); }
@Override public <T> Object handleTimeout(NativeWebRequest request, Callable<T> task) throws Exception {
System.out.println("handleTimeout called.");
return RESULT_NONE; }
@Override public <T> void afterCompletion(NativeWebRequest request, Callable<T> task) throws Exception { log("afterCompletion called."); }
private static void log(String msg) { System.out.printf("%s CallableInterceptor [%s] - %s%n", LocalTime.now(), Thread.currentThread().getName(), msg); } }
 package com.logicbig.example;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.web.context.request.async.WebAsyncManager; import org.springframework.web.context.request.async.WebAsyncUtils; import org.springframework.web.servlet.AsyncHandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import java.time.LocalTime;
public class MyAsyncHandlerInterceptor implements AsyncHandlerInterceptor { private static final Object CALLABLE_INTERCEPTOR_KEY = new Object();
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log("preHandle called.", request);
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); asyncManager.registerCallableInterceptor( CALLABLE_INTERCEPTOR_KEY, new MyCallableProcessingInterceptor()); return true;
}
@Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log("postHandle called.", request); }
@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log("afterCompletion called.", request); }
@Override public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log("afterConcurrentHandlingStarted called. ", request); }
private static void log(String msg, HttpServletRequest request) { System.out.printf("%s Interceptor [%s] DispatcherType: %s - %s%n", LocalTime.now(), Thread.currentThread().getName(), request.getDispatcherType(), msg); } }
 package com.logicbig.example;
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import java.time.LocalTime; import java.util.concurrent.Callable;
@Controller public class MyWebController { @RequestMapping("/test") @ResponseBody public Callable<String> handleTestRequest() {
log("handler called.");
Callable<String> callable = new Callable<String>() { @Override public String call() throws Exception { log("callable#async task started."); Thread.sleep(500); log("callable#async task finished"); return "async result"; } };
log("handler finished"); return callable; }
private static void log(String msg) { System.out.printf("%s Controller [%s] - %s%n", LocalTime.now(), Thread.currentThread().getName(), msg); } }
 package com.logicbig.example;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
@EnableWebMvc @ComponentScan @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyAsyncHandlerInterceptor()); }
@Override public void configureAsyncSupport(AsyncSupportConfigurer configurer) { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(10); executor.setThreadNamePrefix("MvcAsync"); executor.initialize(); configurer.setTaskExecutor(executor); } }
pom.xml: <?xml version="1.0" encoding="UTF-8"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <groupId>com.logicbig.example</groupId> <artifactId>async-callable-process-interceptor</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>7.0.6</version> </dependency> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>6.1.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>7.0.6</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>6.0.3</version> <scope>test</scope> </dependency> <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest</artifactId> <version>3.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> <version>3.26.3</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.5.1</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.15.0</version> <configuration> <source>25</source> <target>25</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.eclipse.jetty.ee11</groupId> <artifactId>jetty-ee11-maven-plugin</artifactId> <version>12.1.6</version> <configuration> <webApp> <contextPath>/</contextPath> </webApp> <stopPort>9966</stopPort> <stopKey>foo</stopKey> </configuration> </plugin> </plugins> </build> </project>
Original Post
|
|