Spring Boot Filter 过滤器
LP学长 人气:0前言:
要想使用 filter,需要写一个方法继承 Filter 类,我们写如下两个自己的 Filter 类,首先是 FirstFilter
类,其中 @Order
里边的数字越小代表越先被该 Filter 过滤,@WebFilter
代表这是个 Filter 类并把这个类注入到容器中:
/**** imports ****/ @Order(1) @WebFilter(filterName="firstFilter", urlPatterns="/*") public class FirstFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("first filter 1"); chain.doFilter(request, response); System.out.println("first filter 2"); } @Override public void destroy() { } }
然后是第二个 Filter,SecondFilter
类:
/**** imports ****/ @Order(2) @WebFilter(filterName="secondFilter", urlPatterns="/*") public class SecondFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("second filter 1"); System.out.println("before:" + response); chain.doFilter(request, response); System.out.println("after:" + response); System.out.println("second filter 2"); } @Override public void destroy() { } }
然后我们把 Controller
类也写出来:
/**** imports ****/ @RestController public class TestController { @GetMapping("/test1") public String test1() { System.out.println("method in controller"); return "test1"; } }
最后是 Spring Boot 的主方法入口,注意,由于我们使用注解注入的 Filter,所以要在下边这个 Application 类中加入@ServletComponentScan
注解:
/**** imports ****/ @SpringBootApplication @ServletComponentScan public class ExecutorTestApplication { public static void main(String[] args) { ConfigurableApplicationContext applicationContext = SpringApplication.run(ExecutorTestApplication.class, args); } }
首先我们先来看一下执行结果,启动后访问 127.0.0.1:8080/test1
,在后台中打印如下信息:
我们可以看出代码执行的流程:
- 请求被 firstFilter 截获,打印出 first filter 1
- 执行 chain.doFilter(request, response),这句话代表着请求会转发给过滤器链上下一个对象,也就是 secondFilter,所以打印出 secondFilter 里的 second filter 1
- 执行 secondfilter 里的 chain.dofilter() 方法,请求再转发给下一个对象,由于没有其他的 filter 了,所以会转发给 controller,打印出了 controller 类中的 method in controller
- 内存栈里调用 secondFilter 的 print("second filter 2")
- 内存栈里调用 firstfilter 的 print("first filter 1")
所以如果在自己实现的 Filter 类的 doFilter 方法里不加 chain.doFilter(req, rep) 是不行的,那样会导致请求到了这个 filter 里就不再往下走了,永远进不了 controller 中。
我们也可以在 print("before:" + response) 和 print("after:" + response) 这两个地方打上断点,然后调试一下,会发现在 before 那里的 response 里是什么都么有的,而在 after 那里的 response 里则是已经有了 test1 字符串,也就是说 controller 类 test1 方法的返回值已经添加进了 response,所以如果想要对请求的 response 做一下过滤处理,那么要在 chain.doFilter(res, rep) 之后写你的逻辑。
加载全部内容