过滤器(Filter)与拦截器(Interceptor)知识点总结
过滤器(Filter)与拦截器(Interceptor)知识点总结
请求 → Filter → DispatcherServlet → Interceptor → Controller → Interceptor (post/after) → DispatcherServlet → 响应返回
一、Filter(过滤器)
1. 基本概念
-
属于 Servlet 规范,在 请求到达 Servlet 之前 / 响应返回客户端之前 进行统一处理。
-
典型场景:
- 登录校验
- 字符编码设置
- 请求日志、性能监控
- 静态资源过滤(压缩、缓存、跨域)
2. 核心方法
实现 javax.servlet.Filter
接口,三个方法:
public class DemoFilter implements Filter {// 初始化方法:服务器启动时调用一次@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("Filter init");}// 拦截方法:请求经过时调用,可多次执行@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {System.out.println("Filter 拦截请求");chain.doFilter(request, response); // 放行}// 销毁方法:服务器关闭时调用一次@Overridepublic void destroy() {System.out.println("Filter destroy");}
}
📌 注意:
init()
和destroy()
有默认空实现,可省略不写。- 重点在
doFilter()
,必须实现。
3. Spring Boot 配置
@WebFilter("/*")
public class DemoFilter implements Filter { ... }@ServletComponentScan
@SpringBootApplication
public class TliasWebManagementApplication { ... }
4. 代码示例(JWT 校验)
- 如果请求路径包含
/login
→ 放行。 - 其他请求 → 校验
token
头部是否存在、能否解析 JWT。 - 如果不合法 → 返回 JSON
NOT_LOGIN
。 - 如果合法 →
chain.doFilter()
放行。
package com.itheima.filter;import com.alibaba.fastjson.JSONObject;
import com.itheima.pojo.Result;
import com.itheima.util.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@Slf4j
@WebFilter("/*")
public class DemoFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("DemoFilter init");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain Chain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;String url = request.getRequestURI();log.info("请求的url是:{}", url);if(url.contains("/login")){log.info("登录操作");Chain.doFilter(servletRequest, servletResponse);return;}// 放行String jwt = request.getHeader("token");if(!StringUtils.hasLength(jwt)){log.info("jwt为空");Result error = Result.error("NOT_LOGIN");// 手动转jsonString notlogin = JSONObject.toJSONString(error);response.getWriter().write(notlogin);return;}try{JwtUtils.parseJwt(jwt);}catch (Exception e){log.info("解析jwt失败");e.printStackTrace();Result error = Result.error("NOT_LOGIN");// 手动转jsonString notlogin = JSONObject.toJSONString(error);response.getWriter().write(notlogin);return;}log.info("jwt正常");Chain.doFilter(servletRequest, servletResponse);}@Overridepublic void destroy() {System.out.println("DemoFilter destroy");}
}
package com.itheima;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;@ServletComponentScan
@SpringBootApplication
public class TliasWebManagementApplication {public static void main(String[] args) {SpringApplication.run(TliasWebManagementApplication.class, args);}}
二、Interceptor(拦截器)
1. 基本概念
-
属于 Spring MVC,作用在 Controller 方法调用前后。
-
提供三个回调方法:
preHandle()
:Controller 执行前调用,可决定是否放行。postHandle()
:Controller 执行后、视图渲染前调用。afterCompletion()
:请求完成后调用,用于资源清理、异常处理。
2. 核心代码
@Component
public class LoginCheckInterceptor implements HandlerInterceptor {// 进入 Controller 前执行@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("preHandle");return true; // 返回 false 则拦截}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {System.out.println("postHandle");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {System.out.println("afterCompletion");}
}
3. 配置方式
@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate LoginCheckInterceptor loginCheckInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**") // 拦截所有路径.excludePathPatterns("/login"); // 排除登录}
}
4. JWT 校验逻辑
- 与 Filter 类似:
preHandle()
中校验 /login
直接放行。
其余请求 → 获取 token
,调用 JwtUtils.parseJwt()
解析。
校验失败 → 返回 NOT_LOGIN
,并 return false
拦截请求。
校验成功 → 返回 true
放行。
package com.itheima.config;import com.itheima.interceptor.LoginCheckinterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate LoginCheckinterceptor loginCheckinterceptor;public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginCheckinterceptor).addPathPatterns("/**").excludePathPatterns("/login");}
}
package com.itheima.interceptor;import com.alibaba.fastjson.JSONObject;
import com.itheima.pojo.Result;
import com.itheima.util.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@Slf4j
@Component
public class LoginCheckinterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("preHandle");HttpServletRequest req = (HttpServletRequest) request;HttpServletResponse res = (HttpServletResponse) response;String url = req.getRequestURI();log.info("请求的url是:{}", url);if(url.contains("/login")){log.info("登录操作");return true;}// 放行String jwt = req.getHeader("token");if(!StringUtils.hasLength(jwt)){log.info("jwt为空");Result error = Result.error("NOT_LOGIN");// 手动转jsonString notlogin = JSONObject.toJSONString(error);res.getWriter().write(notlogin);return false;}try{JwtUtils.parseJwt(jwt);}catch (Exception e){log.info("解析jwt失败");e.printStackTrace();Result error = Result.error("NOT_LOGIN");// 手动转jsonString notlogin = JSONObject.toJSONString(error);res.getWriter().write(notlogin);return false;}log.info("jwt正常");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("postHandle");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("afterCompletion");}
}
三、Filter 与 Interceptor 对比
对比点 | Filter | Interceptor |
---|---|---|
所属规范 | Servlet 规范 | Spring MVC |
执行时机 | 在 Servlet 前后,对所有请求生效(包含静态资源) | 在 Controller 前后,对 Spring 管理的请求生效 |
方法 | init() 、doFilter() 、destroy() | preHandle() 、postHandle() 、afterCompletion() |
配置方式 | @WebFilter + @ServletComponentScan | 实现 WebMvcConfigurer.addInterceptors |
应用场景 | 登录校验、日志、编码、跨域、静态资源处理 | 登录校验、权限控制、业务逻辑相关拦截 |
灵活性 | 粒度较粗,局限于 Servlet 层 | 粒度更细,可获取 Controller、方法信息 |
生命周期 | Filter 在容器启动时初始化,销毁时关闭 | Interceptor 随 Spring 容器创建和销毁 |
四、总结
-
Filter:更底层,适合做通用、与业务无关的请求处理(编码、日志、安全过滤)。
-
Interceptor:更贴近业务,适合做权限控制、操作日志、业务规则等。
-
在 JWT 校验中:
- Filter 适合做全局安全入口。
- Interceptor 适合做精细化的接口级别权限控制。