Servlet包中提供了Filter接口供我们实现自定义过滤器。
自定义拦截器可以参考我之前的文章
与之不同的是,拦截器是Spring框架提供的功能,而Filter过滤器是Servlet提供的。下面是拦截器与过滤器的一些主要区别:
- Filter由Servlet包提供,只能用于Web应用,不能使用Spring容器资源;拦截器由Spring提供,既能用于Web应用,也能用于Application和Swing应用,能使用Spring容器资源。
- Filter只能在Servlet的前后起作用;而拦截器能深入到方法前后、异常抛出前后。
- Filter基于函数回调;拦截器基于java的反射机制。
- ……
实现自定义过滤器
- 1、实现Filter接口,自定义过滤器
- 2、注册过滤器
我们可以定义多个过滤器,形成一个过滤链,执行的顺序可以在注册的时候设置优先级,优先级的数字越小优先级越大
自定义过滤器
定义过滤器1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
@Slf4j public class MyFilter1 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { log.info("----- init filter1 -----"); }
@Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { log.info("----- doFilter1 -----"); HttpServletRequest httpRequest = (HttpServletRequest) servletRequest; httpRequest.setAttribute("name", "zhangting"); filterChain.doFilter(servletRequest, servletResponse); }
@Override public void destroy() { log.info("----- destroy filter1 -----"); } }
|
定义过滤器2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
@Slf4j public class MyFilter2 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { log.info("----- init filter2 -----"); }
@Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { log.info("----- doFilter2 -----"); HttpServletRequest httpRequest = (HttpServletRequest) servletRequest; httpRequest.setAttribute("city", "nanjing"); filterChain.doFilter(servletRequest, servletResponse); }
@Override public void destroy() { log.info("----- destroy filter2 -----"); } }
|
注册过滤器
编写一个javaconfig类来注册过滤器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
@Slf4j @Configuration public class FilterConfig {
@Bean @Primary public FilterRegistrationBean<MyFilter1> registerMyFilter1() { log.info("register MyFilter1..."); FilterRegistrationBean<MyFilter1> filterRegistrationBean = new FilterRegistrationBean<MyFilter1>(); filterRegistrationBean.setFilter(new MyFilter1()); filterRegistrationBean.addUrlPatterns("/v1/filter"); filterRegistrationBean.setName("myFilter1"); filterRegistrationBean.setOrder(1); return filterRegistrationBean; }
@Bean public FilterRegistrationBean<MyFilter2> registerMyFilter2() { log.info("register MyFilter2..."); FilterRegistrationBean<MyFilter2> filterRegistrationBean = new FilterRegistrationBean<MyFilter2>(); filterRegistrationBean.setFilter(new MyFilter2()); filterRegistrationBean.addUrlPatterns("/v1/filter"); filterRegistrationBean.setName("myFilter2"); filterRegistrationBean.setOrder(2); return filterRegistrationBean; } }
|
测试
编写测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Slf4j @RestController @RequestMapping("/v1") public class TestController {
@GetMapping("/filter") public ResponseEntity<?> filter(HttpServletRequest request) { Map<String, String> map = new HashMap<>(); map.put("name", request.getAttribute("name").toString()); map.put("city", request.getAttribute("city").toString()); return new ResponseEntity<>(map, HttpStatus.OK); } }
|
启动服务,两个过滤器会在启动的时候进行注册及调用init方法对过滤器进行初始化。
使用postman对/v1/filter接口发起请求
查看日志可以得知,过滤器按照我们设置的执行顺序执行,先执行过滤器1,再执行过滤器2。
我们在过滤器1、2中添加的测试值成功的返回到了前台,测试成功