当前位置:首页 > 后端开发 > 正文

java拦截器怎么配置

va拦截器配置分三步:实现HandlerInterceptor接口或继承适配器类;创建 配置类并注册到InterceptorRegistry;通过addPathPatterns指定拦截路径,excludePathPatterns排除无需拦截的URL。

是关于Java拦截器配置的详细说明,涵盖实现方式、核心方法解析及典型应用场景:

基础概念与作用

Java拦截器(Interceptor)是Spring MVC框架中用于处理HTTP请求的重要组件,其功能类似于AOP面向切面编程思想的具体实现,它能够在控制器方法执行前后插入自定义逻辑,例如权限校验、日志记录、参数校验等操作,与过滤器不同,拦截器仅针对Controller层的请求生效,支持更细粒度的控制。

两种实现方式对比

特性 实现HandlerInterceptor接口 继承HandlerInterceptorAdapter抽象类
需重写的方法数量 必须完整实现preHandle/postHandle/afterCompletion三个方法 只需覆盖preHandle方法即可,其他方法已有默认空实现
开发效率 较低(需要全部实现) 较高(聚焦核心逻辑)
适用场景 需要完全自定义所有阶段行为时 多数情况只需前置处理(如鉴权)

推荐优先选择继承适配器的方式,例如创建登录校验拦截器时,通常只需要关注preHandle方法的返回值即可决定是否放行请求。

配置步骤详解

创建拦截器类

以实现HandlerInterceptorAdapter为例:

java拦截器怎么配置  第1张

@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标准实现,不依赖特定框架

0