SpringBoot中使用借助Interceptor编写拦截器呢?
下文笔者讲述SpringBoot中编写拦截器的方法分享
学习完本篇之后,你将掌握SpringBoot中拦截器的编写方法,如下所示
学习完本篇之后,你将掌握SpringBoot中拦截器的编写方法,如下所示
SpringBoot拦截器的编写方法
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类似
例:拦截器的示例
package testspringboot.test9interceptor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Test9Main {
public static void main(String[] args) {
SpringApplication.run(Test9Main.class, args);
}
}
controller类
package testspringboot.test9interceptor;
import java.util.concurrent.Callable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@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
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;
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");
}
}
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;
@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());
}
}
配置拦截器
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可以看到前后使用的是两个线程;
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。


