在springboot中使用拦截器也比较简单,实现HandlerInterceptor或者AsyncHandlerInterceptor接口,再从配置里添加一下拦截器就完成了;
AsyncHandlerInterceptor接口继承了HandlerInterceptor,多了一个afterConcurrentHandlingStarted方法:


接口里的方法:
- preHandle:在Controller之前执行,可以判断参数,执行的controller方法等,返回值为boolean,返回true继续往下运行(下面的拦截器和controller),否则开始返回操作(执行之前的拦截器返回等操作);
- postHandle:在Controller之后,视图返回前执行,可对ModelAndView进行处理再返回;
- afterCompletion:请求完成后执行;
- afterConcurrentHandlingStarted:controller返回值是java.util.concurrent.Callable时才会调用该方法并使用新线程运行;
方法执行顺序有两种:
- preHandle -> 执行Controller -> postHandle -> afterCompletion;
- preHandle -> 执行Controller -> afterConcurrentHandlingStarted -> callable线程执行call()方法 -> 新线程开始preHandle -> postHandle -> afterCompletion;(controller方法返回Callable对象时)
配置拦截器:
实现WebMvcConfigurer接口里的addInterceptors方法,使用参数InterceptorRegistry对象添加自己的拦截器,可以添加指定拦截路径或者去掉某些过滤路径,还可以设置拦截器的优先级order,优先级由小到大,默认0;
多个拦截器的执行顺序:
preHandle方法按照order由小到大顺序,执行完controller后,其他方法则反向顺序,跟过滤器Filter类似;
测试启动类,默认配置:
- /**
- * 2023年3月16日下午4:56:23
- */
- package testspringboot.test9interceptor;
-
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
-
- /**
- * @author XWF
- *
- */
- @SpringBootApplication
- public class Test9Main {
-
- /**
- * @param args
- */
- public static void main(String[] args) {
- SpringApplication.run(Test9Main.class, args);
- }
-
- }
controller类:
- /**
- * 2023年3月16日下午4:58:02
- */
- package testspringboot.test9interceptor;
-
- import java.util.concurrent.Callable;
-
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- /**
- * @author XWF
- *
- */
- @RestController
- @RequestMapping("/interceptor")
- public class Test9Controller {
-
- @RequestMapping("/a")
- public String a(String s) {
- System.out.println(">>>a():" + s);
- return "OK";
- }
-
- @RequestMapping("/b")
- public Callable<String> b() {
- Callable<String> callable = new Callable<String>() {
- @Override
- public String call() throws Exception {
- Thread.sleep(2000);
- System.out.println("call() thread id=" + Thread.currentThread().getId());
- Thread.sleep(2000);
- return "abcdefg";
- }
- };
- System.out.println(">>>b()");
- return callable;
- }
-
- }
两个自定义拦截器1和2:
- /**
- * 2023年3月16日下午5:14:14
- */
- package testspringboot.test9interceptor;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- import org.springframework.web.servlet.HandlerInterceptor;
- import org.springframework.web.servlet.ModelAndView;
-
- /**
- * @author XWF
- *
- */
- public class MyInterceptor1 implements HandlerInterceptor {
-
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
- throws Exception {
- System.out.println("preHandle 1, handler=" + handler);
- return request.getQueryString().length() < 10 ? true : false;
- }
-
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
- ModelAndView modelAndView) throws Exception {
- System.out.println("postHandle 1");
- }
-
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
- throws Exception {
- System.out.println("afterCompletion 1");
- }
-
- }
- /**
- * 2023年3月16日下午5:15:28
- */
- package testspringboot.test9interceptor;
-
- import java.util.Date;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- import org.springframework.stereotype.Component;
- import org.springframework.web.servlet.AsyncHandlerInterceptor;
- import org.springframework.web.servlet.ModelAndView;
-
- /**
- * @author XWF
- *
- */
- @Component
- public class MyInterceptor2 implements AsyncHandlerInterceptor {
-
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
- throws Exception {
- System.out.println("preHandle 2 " + new Date() + " ThreadId=" + Thread.currentThread().getId());
- return true;
- }
-
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
- ModelAndView modelAndView) throws Exception {
- System.out.println("postHandle 2");
- }
-
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
- throws Exception {
- System.out.println("afterCompletion 2");
- }
-
- @Override
- public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler)
- throws Exception {
- System.out.println("afterConcurrentHandlingStarted 2 " + new Date());
- }
-
- }
配置拦截器:
- /**
- * 2023年3月16日下午5:20:31
- */
- package testspringboot.test9interceptor;
-
- import javax.annotation.Resource;
-
- import org.springframework.context.annotation.Configuration;
- import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
- import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
- /**
- * @author XWF
- *
- */
- @Configuration
- public class MyInterceptorConfig implements WebMvcConfigurer {
-
- @Resource
- MyInterceptor2 myinterceptor2;
-
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- registry.addInterceptor(new MyInterceptor1())
- .addPathPatterns("/interceptor/a") //添加拦截路径,两种参数List<String>和String ...
- .excludePathPatterns("/interceptor/b") //排除路径,两种参数List<String>和String ...
- .order(1); //设置拦截器顺序,由小到大,默认0
- registry.addInterceptor(myinterceptor2); //也可以使用spring管理的对象
- }
-
- }
发送一个post测试请求:http://192.168.1.30:8080/interceptor/a?s=hello,拦截器2的order默认0,拦截器1的order为1,preHandle先执行2的,controller执行之后,剩下的Handle都是先执行1再执行2的;

发送preHandle返回false的请求:http://192.168.1.30:8080/interceptor/a?s=hello123456789,拦截器1的preHandle返回false后,直接执行2的afterCompletion;

发送测试callable的请求:http://192.168.1.30:8080/interceptor/b?s=hello,拦截路径配置跳过拦截器1只执行拦截器2,通过threadid可以看到前后使用的是两个线程;

到此这篇关于SpringBoot使用Interceptor拦截器的文章就介绍到这了,更多相关SpringBoot使用Interceptor拦截器内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!