java拦截器怎么配置
- 后端开发
- 2025-07-26
- 6
是关于Java拦截器配置的详细说明,涵盖实现方式、核心方法解析及典型应用场景:
基础概念与作用
Java拦截器(Interceptor)是Spring MVC框架中用于处理HTTP请求的重要组件,其功能类似于AOP面向切面编程思想的具体实现,它能够在控制器方法执行前后插入自定义逻辑,例如权限校验、日志记录、参数校验等操作,与过滤器不同,拦截器仅针对Controller层的请求生效,支持更细粒度的控制。
两种实现方式对比
特性 | 实现HandlerInterceptor接口 | 继承HandlerInterceptorAdapter抽象类 |
---|---|---|
需重写的方法数量 | 必须完整实现preHandle/postHandle/afterCompletion三个方法 | 只需覆盖preHandle方法即可,其他方法已有默认空实现 |
开发效率 | 较低(需要全部实现) | 较高(聚焦核心逻辑) |
适用场景 | 需要完全自定义所有阶段行为时 | 多数情况只需前置处理(如鉴权) |
推荐优先选择继承适配器的方式,例如创建登录校验拦截器时,通常只需要关注preHandle方法的返回值即可决定是否放行请求。
配置步骤详解
创建拦截器类
以实现HandlerInterceptorAdapter为例:
@Component // 确保被Spring扫描到 public class AuthCheckInterceptor extends HandlerInterceptorAdapter { @Autowired private UserService userService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 从Session获取用户信息 User currentUser = (User) request.getSession().getAttribute("loginUser"); if (currentUser == null) { // 未登录则重定向到登录页 response.sendRedirect("/login"); return false; // 阻止继续执行后续流程 } // 已登录用户放行 return true; } }
关键点:通过
@Component
注解注册为Bean,方便后续注入到配置类中,实际业务中可在此添加更复杂的判断逻辑,如角色权限验证等。
注册拦截器到MVC体系
创建配置类实现WebMvcConfigurer接口:
@Configuration public class WebConfig implements WebMvcConfigurer { @Autowired private AuthCheckInterceptor authInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { // 添加拦截路径规则 registry.addInterceptor(authInterceptor) .addPathPatterns("/admin/", "/api/") // 需要拦截的URL模式 .excludePathPatterns("/login", "/register"); // 排除无需拦截的路径 } }
参数说明:
addPathPatterns()
:指定要拦截的请求路径集合,支持Ant风格表达式(如匹配所有层级路径);excludePathPatterns()
:排除特定路径不被拦截,常用于静态资源或公开接口;- 多个拦截器按注册顺序形成链条,可通过调整注册顺序控制执行优先级。
多拦截器顺序控制示例
当系统中存在多个拦截器时,它们的执行顺序由注册顺序决定:
@Configuration public class MultiInterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { // 先注册的拦截器先执行 registry.addInterceptor(new LoggingInterceptor()) // 第一个执行 .addPathPatterns("/"); registry.addInterceptor(new SecurityInterceptor()); // 第二个执行 } }
注意:每个拦截器的
preHandle
返回值会影响后续流程是否继续,若某个拦截器返回false
,则整个链路终止。
核心方法生命周期解析
方法名 | 触发时机 | 典型用途 | 注意事项 |
---|---|---|---|
preHandle() |
控制器方法执行前 | 权限校验、参数预处理 | 返回false 可立即中断请求处理流程 |
postHandle() |
控制器方法执行后,视图渲染前 | 修改ModelAndView对象属性 | 仅当preHandle 返回true 时才会调用 |
afterCompletion() |
整个请求处理完毕(包括异常情况) | 资源清理、统一日志记录 | 适合做收尾工作,如关闭数据库连接池 |
常见应用场景案例
案例1:全局异常捕获
public class GlobalExceptionInterceptor extends HandlerInterceptorAdapter { @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { if (ex != null) { PrintWriter writer = response.getWriter(); writer.write("{"code":500,"msg":"系统错误"}"); writer.flush(); } } }
此拦截器会在所有请求完成后检查是否存在未处理的异常,并返回标准化的错误响应。
案例2:性能监控统计
public class PerformanceMonitorInterceptor implements HandlerInterceptor { private static final Logger logger = LoggerFactory.getLogger(PerformanceMonitorInterceptor.class); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { long startTime = System.currentTimeMillis(); request.setAttribute("startTime", startTime); return true; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { long cost = System.currentTimeMillis() (Long) request.getAttribute("startTime"); logger.info("请求{}耗时{}ms", request.getRequestURI(), cost); } }
通过记录请求开始时间和结束时间差,实现接口响应时间的监控统计。
FAQs
Q1:如何让拦截器只对特定角色的用户生效?
A:在preHandle
方法中结合权限管理系统(如Shiro或Spring Security)进行角色判断,例如使用Shiro框架时,可通过SecurityUtils.getSubject().hasRole("ADMIN")
来判断当前用户是否具有管理员权限,若无则抛出异常或跳转至提示页面。
Q2:拦截器与过滤器有什么区别?
A:主要区别在于作用范围和执行时机,拦截器仅作用于Controller层的请求处理过程,而过滤器(Filter)属于Servlet规范的一部分,可以拦截所有进入应用的请求(包括静态资源),拦截器能够访问Spring的上下文环境,便于集成其他组件;而过滤器基于Java EE标准实现,不依赖特定框架