本文目录导读:

在Java Web开发中,规范请求拦截流程的核心在于分层治理、职责清晰、有序执行,下面我从核心原则、标准流程(Filter/Interceptor)、常见场景规范以及代码示例四个维度来梳理。
核心原则
- 单一职责:每个拦截器只负责一件事(如仅做登录校验,不做权限判断)。
- 顺序敏感:拦截器链的执行顺序至关重要(如:日志 -> 鉴权 -> 限流 -> 业务处理)。
- 无状态:拦截器内不持有用户状态,用户信息通过
ThreadLocal或请求属性传递。 - 快速失败:非核心功能(如日志)失败不应阻塞主流程,但核心功能(如鉴权)失败必须阻断。
- 性能可控:避免在拦截器中做耗时操作(如复杂计算、远程调用),必要时应引入缓存或异步。
标准流程与执行顺序
Filter(过滤器)层面(Servlet 规范)
通常用于最底层、跨切面的粗粒度处理,如字符编码、跨域、安全防护。
[客户端请求]
↓
[Filter 1: CharacterEncodingFilter] // 设置编码
↓
[Filter 2: CorsFilter] // 跨域处理
↓
[Filter 3: SecurityFilter] // XSS/CSRF 防护
↓
[DispatcherServlet] // 进入 Spring MVC
↓
[Interceptor 1: LogInterceptor] // 请求日志(前置)
↓
[Interceptor 2: AuthInterceptor] // 登录/Token 校验
↓
[Interceptor 3: RateLimitInterceptor] // 限流
↓
[Controller] // 业务处理
↓
[Interceptor 3: 后置] // 限流后置(通常无操作)
↓
[Interceptor 2: 后置] // 鉴权后置(通常无操作)
↓
[Interceptor 1: 后置/完成] // 日志记录结束时间
↓
[Filter 响应链] out
Interceptor(拦截器)层面(Spring MVC 专属)
更贴近业务逻辑,可灵活操作 ModelAndView,适合做:身份校验、权限控制、日志审计、参数预处理。
preHandle:请求前,返回true放行,返回false阻断。postHandle:Controller 执行后、视图渲染前。afterCompletion:视图渲染后、请求完全结束前(通常用于资源清理)。
常见场景的规范实现
鉴权拦截规范
- Token 校验:从 Header 或 Cookie 提取,验证签名和过期时间。
- ThreadLocal 传递用户信息:防止数据污染,请求结束务必
remove()。 - 白名单过滤:登录、注册、静态资源等接口应跳过鉴权。
日志审计规范
- 必须记录:请求路径、请求参数、响应状态码、耗时、用户ID(如有)。
- 必须脱敏:密码、身份证、手机号等敏感字段在记录前做 处理。
- 异步写入:建议通过消息队列或异步线程写日志,避免阻塞主流程。
参数校验与防篡改规范
- 前置参数校验:使用
@Valid或自定义验证器,快速返回错误。 - 签名校验:对于敏感接口,对请求体 + 时间戳做 HMAC 签名验证,防止重放攻击。
限流与防刷规范
- 基于 IP 或 Token:使用桶算法(RateLimiter)或滑动窗口。
- 优先级低于鉴权:正确区分“未登录的游客”和“已登录的恶意用户”。
实战代码示例(Spring Boot)
定义自定义拦截器(Token 校验 + 日志)
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// 1. 白名单放行
String uri = request.getRequestURI();
if (uri.startsWith("/api/public/") || uri.equals("/login")) {
return true;
}
// 2. 提取 Token
String token = request.getHeader("Authorization");
if (token == null || !jwtUtil.validateToken(token)) {
response.setStatus(401);
response.getWriter().write("{\"code\":401,\"msg\":\"未授权\"}");
return false;
}
// 3. 解析用户,存入 ThreadLocal
User user = jwtUtil.parseUser(token);
UserContext.set(user);
// 4. 记录请求日志(简单示例)
log.info("用户: {} 请求: {}", user.getId(), uri);
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
// 必须清理 ThreadLocal,防止内存泄漏
UserContext.remove();
}
}
注册拦截器并指定顺序
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private AuthInterceptor authInterceptor;
@Autowired
private RateLimitInterceptor rateLimitInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 顺序1:日志拦截器(最先执行)
registry.addInterceptor(logInterceptor)
.addPathPatterns("/**");
// 顺序2:限流拦截器
registry.addInterceptor(rateLimitInterceptor)
.addPathPatterns("/api/**")
.order(1);
// 顺序3:鉴权拦截器(最后执行,保证已限流)
registry.addInterceptor(authInterceptor)
.addPathPatterns("/api/**")
.excludePathPatterns("/api/public/**", "/login")
.order(2);
}
}
使用 Filter 做全局限流(可选)
@Component
@Order(1) // 优先级最高
public class RateLimitFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
String ip = request.getRemoteAddr();
if (!rateLimiter.tryAcquire(ip)) {
response.setStatus(429);
return;
}
chain.doFilter(request, response);
}
}
最佳实践总结
| 场景 | 使用位置 | 备注 |
|---|---|---|
| 跨域、编码 | Filter | 与业务无关,全局生效 |
| XSS/CSRF | Filter | 安全基座 |
| Token 校验 | Interceptor preHandle | 业务相关,可获取 Spring 容器 |
| 权限校验 | Interceptor preHandle | 依赖当前登录用户 |
| 请求日志 | Interceptor preHandle | 可记录请求前/后时间 |
| 参数脱敏 | Interceptor afterCompletion | 响应体已生成 |
| 全局异常 | @ControllerAdvice | 不放在拦截器中 |
| 性能不好的操作 | 异步队列 | 不要阻塞拦截流程 |
最后总结一句话:
“Filter 做底层安全与编码,Interceptor 做登录与权限,业务逻辑放 Controller,异常统一由 @ControllerAdvice 处理。”
如果你需要针对某个具体场景(如微服务下如何利用网关统一拦截、或如何设计防重放拦截),可以告诉我,我可以进一步展开。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播