Java拦截器案例如何编写配置

wen java案例 28

Java拦截器案例如何编写配置:从零到实战的完整指南

目录导读


什么是拦截器?核心概念与作用

拦截器(Interceptor) 是Java Web开发中一种面向切面编程(AOP)的实现机制,主要用于在请求处理流程的特定阶段(如Controller方法执行前、后、完成后)插入自定义逻辑。

Java拦截器案例如何编写配置

核心作用包括:

  • 身份认证与权限校验:拦截未登录用户访问受保护资源
  • 请求日志记录:记录接口调用时间、参数、结果
  • 性能监控:统计接口处理耗时
  • 数据预处理:统一设置请求头、编码字符等
  • 资源释放与清理:如关闭数据库连接、清除临时文件

工作流程:

请求 → 拦截器.preHandle() → Controller → 拦截器.postHandle() → 视图渲染 → 拦截器.afterCompletion() → 响应

preHandle()返回false时,请求将被阻断,不再继续执行后续流程。


拦截器 vs 过滤器:本质区别与选型建议

很多开发者容易混淆这两个概念,以下是关键对比:

对比维度 拦截器(Interceptor) 过滤器(Filter)
依赖容器 基于Spring IoC容器 基于Servlet容器
作用范围 仅拦截Controller请求 拦截所有URL资源(包括静态文件)
处理能力 可获取Spring Bean、AOP上下文 功能较基础,无Spring支持
典型场景 业务逻辑校验、参数处理 编码设置、跨域、XSS过滤

选型建议:

  • 需要操作Spring Bean(如注入Service) → 用拦截器
  • 纯Web层通用处理(如设置字符集) → 用过滤器
  • 同时需要两种能力 → 可组合使用

Spring MVC拦截器实战:编写配置步骤详解

步骤1:创建拦截器类

实现HandlerInterceptor接口,并重写三个方法:

public class AuthInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 返回true放行,false拦截
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // Controller执行后、视图渲染前
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 请求完全处理后
    }
}

步骤2:配置拦截规则(两种方式)

Java配置类(推荐)
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AuthInterceptor())
                .addPathPatterns("/api/**")           // 拦截路径
                .excludePathPatterns("/api/login",    // 排除路径
                                    "/api/register",
                                    "/error",
                                    "/static/**");    // 静态资源排除
    }
}
XML配置
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/api/**"/>
        <mvc:exclude-mapping path="/api/login"/>
        <mvc:exclude-mapping path="/api/register"/>
        <bean class="com.example.interceptor.AuthInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

步骤3:注册与生效

  • Spring Boot项目自动扫描@Configuration
  • 传统Spring项目需在spring-mvc.xml中开启<mvc:annotation-driven/>

完整案例:用户权限校验拦截器(含代码)

需求描述

拦截/admin/**下的所有请求,校验请求头中的Token是否有效,无效则返回401。

拦截器实现

public class TokenAuthInterceptor implements HandlerInterceptor {
    @Autowired
    private AuthService authService;  // 注入Spring Bean必须配合@Component
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        String token = request.getHeader("Authorization");
        if (token == null || !authService.validateToken(token)) {
            response.setStatus(401);
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write("{\"code\":401,\"msg\":\"无权限访问\"}");
            return false;
        }
        // 将用户信息放入请求上下文
        request.setAttribute("userId", authService.getUserId(token));
        return true;
    }
}

配置类

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注意:如果拦截器中使用了@Autowired,此处需要用@Bean注入
        registry.addInterceptor(tokenAuthInterceptor())
                .addPathPatterns("/admin/**")
                .excludePathPatterns("/admin/login");
    }
    @Bean
    public TokenAuthInterceptor tokenAuthInterceptor() {
        return new TokenAuthInterceptor();
    }
}

关键:因为拦截器在Spring Bean容器创建前就被实例化,因此需通过@Bean方式注册。

测试验证

  • 访问/admin/dashboard(不带Token)→ 返回401
  • 访问/admin/dashboard(带有效Token)→ 返回正常数据
  • 访问/admin/login(排除路径)→ 可直接访问

拦截器常见配置陷阱与解决方案

陷阱1:拦截器不生效

  • 原因:未实现WebMvcConfigurer或Java配置类未被扫描
  • 解决:检查@Configuration注解,Spring Boot确保配置类在主启动类同层级或子包

陷阱2:静态资源被拦截

  • 原因:未排除静态资源路径(如/static/**, /css/**等)
  • 解决.excludePathPatterns("/static/**", "/webjars/**")

陷阱3:多个拦截器执行顺序混乱

  • 规则:按注册顺序执行preHandle(先注册先执行),postHandleafterCompletion反向执行
  • 正确做法:按业务依赖顺序注册,拦截器A(日志)→ 拦截器B(认证)

陷阱4:拦截器中注入失败

  • 原因:拦截器通过new创建,非Spring管理
  • 解决:使用@Bean方式注册,或使用@Component并通过registry.addInterceptor(this)注入

高频问答:开发者最常问的5个问题

Q1:拦截器可以访问Controller方法的参数吗? A:可以。preHandle中的Object handler参数是HandlerMethod类型,可通过((HandlerMethod) handler).getMethod()获取方法对象,再通过getParameterAnnotations()获取参数注解和值。

Q2:如何让拦截器只拦截特定HTTP方法(如只拦截POST请求)? A:在preHandle中通过request.getMethod()判断,

if (!"POST".equalsIgnoreCase(request.getMethod())) {
    return true; // 非POST请求直接放行
}

Q3:拦截器抛出异常后如何处理? A:在afterCompletion中捕获异常,或使用Spring的@ControllerAdvice统一异常处理,拦截器本身建议只做校验逻辑,异常交由全局处理器处理。

Q4:多个拦截器可不可以共享数据? A:可以,通过HttpServletRequest.setAttribute()在不同拦截器和Controller间传递数据,例如前一个拦截器将用户信息放入请求上下文,后一个拦截器读取。

Q5:Spring Security和拦截器如何共存? A:Spring Security本质是一组过滤器链,拦截器在其后执行,最佳实践是:Security做整体安全(认证/授权),拦截器做业务特定逻辑(如接口调用频率限制)。


Java拦截器是构建可维护Web应用的利器,核心在于理解其生命周期、正确配置注册方式、以及处理与Spring容器的依赖关系,通过本文的案例和陷阱提示,你可以快速在企业项目中落地拦截器功能,遇到配置问题,优先检查注册方式是否正确、路径模式是否覆盖预期、以及Bean依赖是否生效。

抱歉,评论功能暂时关闭!