Close

Spring MVC - AsyncHandlerInterceptor Examples

Spring MVC 

HandlerInterceptor#afterConcurrentHandlingStarted() method is invoked just before main request thread exists after spawning a new thread for async processing.

package com.logicbig.example;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class MyAsyncHandlerInterceptor extends HandlerInterceptorAdapter {

@Override
public boolean preHandle (HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {

System.out.println("interceptor#preHandle called. Thread: " + Thread
.currentThread().getName());
return true;

}

@Override
public void postHandle (HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {

System.out.println("interceptor#postHandle called. Thread: " +
Thread.currentThread()
.getName());
}

@Override
public void afterCompletion (HttpServletRequest request,
HttpServletResponse response,
Object handler, Exception ex) throws Exception {

System.out.println("interceptor#afterCompletion called Thread.: " +
Thread.currentThread()
.getName());
}

@Override
public void afterConcurrentHandlingStarted (HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {

System.out.println("interceptor#afterConcurrentHandlingStarted. " +
"Thread: " +
Thread.currentThread()
.getName());
}
}

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.util.concurrent.Callable;

@Controller
public class MyWebController {
@RequestMapping("/")
@ResponseBody
public Callable<String> handleTestRequest () {

System.out.println("controller#handler called. Thread: " +
Thread.currentThread()
.getName());

Callable<String> callable = new Callable<String>() {
@Override
public String call () throws Exception {
System.out.println("controller-callable#async task started. Thread: " +
Thread.currentThread()
.getName());
Thread.sleep(300);
System.out.println("controller-callable#async task finished");
return "async result";
}
};

System.out.println("controller#handler finished");
return callable;
}
}

package com.logicbig.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

public class Main {
public static void main (String[] args) {
SpringApplication.run(BootApplication.class, args);
}

@SpringBootApplication
public static class BootApplication extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors (InterceptorRegistry registry) {
registry.addInterceptor(new MyAsyncHandlerInterceptor());
}
}
}

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.logicbig.example</groupId>
<artifactId>async-handler-interceptor-example</artifactId>
<version>1.0-SNAPSHOT</version>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
</parent>

<properties>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
Original Post




This example uses DeferredResult instead of Callable for invoking a long running task.

package com.logicbig.example;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class MyAsyncHandlerInterceptor extends HandlerInterceptorAdapter {

@Override
public boolean preHandle (HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {

System.out.println("interceptor#preHandle called. Thread: " + Thread
.currentThread().getName());
return true;

}

@Override
public void postHandle (HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {

System.out.println("interceptor#postHandle called. Thread: " +
Thread.currentThread()
.getName());
}

@Override
public void afterCompletion (HttpServletRequest request,
HttpServletResponse response,
Object handler, Exception ex) throws Exception {

System.out.println("interceptor#afterCompletion called Thread.: " +
Thread.currentThread()
.getName());
}

@Override
public void afterConcurrentHandlingStarted (HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {

System.out.println("interceptor#afterConcurrentHandlingStarted called. " +
"Thread: " +
Thread.currentThread()
.getName());
}
}

package com.logicbig.example;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.async.DeferredResult;

import java.util.concurrent.Callable;

@Controller
public class MyWebController {
@RequestMapping("/")
@ResponseBody
public DeferredResult<String> handleTestRequest () {

System.out.println("controller#handler called. Thread: " +
Thread.currentThread()
.getName());

final DeferredResult<String> deferredResult = new DeferredResult<>();

new Thread(() -> {
System.out.println("controller-deferred#async task started. Thread: " +
Thread.currentThread()
.getName());
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
deferredResult.setResult("test async result");
System.out.println("controller-deferred#async task finished");
}).start();


System.out.println("controller#handler finished");
return deferredResult;
}
}

package com.logicbig.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

public class Main {
public static void main (String[] args) {
SpringApplication.run(BootApplication.class, args);
}

@SpringBootApplication
public static class BootApplication extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors (InterceptorRegistry registry) {
registry.addInterceptor(new MyAsyncHandlerInterceptor());
}
}
}

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.logicbig.example</groupId>
<artifactId>async-deferred-handler-interceptor</artifactId>
<version>1.0-SNAPSHOT</version>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
</parent>

<properties>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>




See Also