目录
Filter是JavaWeb三大组件(Servlet、Filter、Listener)之一。可以把对资源的请求拦截下来,从而实现一些特殊的功能。
过滤器一般完成一些通用的操作,比如:登录校验、统一编码处理、敏感字符处理等。

首先在自己的Filter类上添加@WebFilter注解
也需要在引导类上添加@ServletComponentScan注解(因为Filter不是SpringBoot的组件)
- @WebFilter("/*")
- public class DemoFilter implements Filter {
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- System.out.println("初始化方法,只会执行一次");
- }
-
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
- System.out.println("所有的请求都需要执行一次该方法");
- //放行
- chain.doFilter(request,response);
- System.out.println("Controller执行完毕返回Filter");
- }
-
- @Override
- public void destroy() {
- System.out.println("销毁方法,也只执行一次");
- }
- }
- @RestController
- @RequestMapping("/user")
- public class UserController {
-
- @RequestMapping("login")
- public void login(){
- System.out.println("进行了登录验证");
- }
- }
启动服务器,浏览器访问localhost:8080/user/login地址观察控制台输出

当一个Web服务存在多个过滤器时,会形成一个过滤器链

过滤器执行顺序根据字符串的自然排序来执行,即由A到Z的顺序。
现在创建A、B两个过滤器
- @WebFilter("/*")
- public class AFilter implements Filter {
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
- System.out.println("执行A过滤器放行前方法");
- chain.doFilter(request, response);
- System.out.println("执行A过滤器放行后方法");
- }
- }
- @WebFilter("/*")
- public class BFilter implements Filter {
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
- System.out.println("执行B过滤器放行前方法");
- chain.doFilter(request, response);
- System.out.println("执行B过滤器放行后方法");
- }
- }
运行访问请求地址观察控制台输出

- @RestController
- @RequestMapping("/user")
- public class UserController {
-
- @RequestMapping("login")
- public void login(HttpServletRequest request){
- request.getSession().setAttribute("token","ok");
- System.out.println("进行了登录验证");
- }
-
- @RequestMapping("/query")
- public void query(){
- System.out.println("查询成功");
- }
- }
- @WebFilter("/*")
- public class DemoFilter implements Filter {
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
- HttpServletRequest req = (HttpServletRequest) request;
- HttpServletResponse res = (HttpServletResponse) response;
- String uri = req.getRequestURI();
- System.out.println(uri);
- //如果是登录请求则放行
- if (uri.contains("login")) {
- chain.doFilter(request, response);
- return;
- }
-
- Object token = req.getSession().getAttribute("token");
- if (token == null) {
- System.out.println("还没有进行登录");
- return;
- }
- if (token.equals("ok")) {
- //已经登陆成功 放行
- chain.doFilter(request, response);
- }
- }
- }
先访问/user/query路径观察控制台输出

登陆后再次访问观察输出。

Interceptor是Spring提供的,用来动态拦截Controller的方法执行。
作用是拦截请求,在指定的方法调用前后,根据业务需要执行预先设定的代码。
在拦截器类上添加注解@Component并实现HandlerInterceptor接口。
- @Component
- public class LoginInterceptor implements HandlerInterceptor {
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- System.out.println("目标资源方法执行前执行。放行返回true,不放行返回false");
- return true;
- }
-
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
- System.out.println("目标资源方法执行后执行");
- }
-
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
- System.out.println("视图渲染完毕后执行");
- }
- }
我们除了定义拦截器类之外,还需要将拦截器注册到Spring中。添加一个配置类
- @Configuration
- public class WebConfig implements WebMvcConfigurer {
- @Autowired
- private LoginInterceptor loginInterceptor;
-
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- //注册拦截器
- registry.addInterceptor(loginInterceptor).addPathPatterns("/**");
- }
- }
访问/user/query路径观察控制台输出

与过滤器有一个不同就是
在注册时除了可以配置拦截路径外还可以配置排除拦截路径


我们在配置里设置了排除对登录请求路径的拦截,那么在拦截器中只需要在执行Controller其他方法之前查询是否登录过即可
- @Component
- public class LoginInterceptor implements HandlerInterceptor {
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- String uri = request.getRequestURI();
- System.out.println(uri);
- Object token = request.getSession().getAttribute("token");
- if (token == null) {
- System.out.println("还没有进行登录");
- return false;
- }
- return true;
- }
-
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
- System.out.println("目标资源方法执行后执行");
- }
-
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
- System.out.println("视图渲染完毕后执行");
- }
- }
