拦截器的介绍及使用

本文详细阐述了Java拦截器的概念、应用场景,包括用户登录校验和资源访问控制,并指导读者如何配置和自定义拦截器,以及理解拦截器链的工作原理。

1. 拦截器概念

动态拦截Actioon调用的对象,使开发者在一个Actioon执行的前后执行一段代码,也可以在Action执行前阻止其执行,同时也提供了一种可以提取Action中可重用部分代码的方式。

2. 作用

动态拦截Action调用的对象(也就是实际项目中的controller层的接口)

3. 适用场景

3.1. 用户登录校验

3.2. 资源拦截,阻止访问

4. 实现拦截器

实现拦截器需要实现HandlerInterceptor接口,HandlerInterceptor接口中有三个方法preHandle、postHandle、afterCompletion。

4.1. preHandle

在Action执行前调用

4.2. postHandle

在Action执行后调用,生成视图前调用

4.3. afterCompletion

在DispatcherServlet完全处理完请求之后被调用,可用于清理资源

4.4. 具体实现

4.4.1. 、配置拦截器

定义一个配置类实现WebMvcConfigurer接口,重写addCorsMappings()方法和addInterceptors()方法


@Configuration //标识这是一个配置类
public class AuthConfig implements WebMvcConfigurer {

    @Autowired
    private GatewayRequestInterceptor gatewayRequestInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //注册gatewayRequestInterceptor拦截器(gatewayRequestInterceptor是我们自己自定义的拦截器类)
        registry.addInterceptor(gatewayRequestInterceptor);
    }
}

4.4.2. 、自定义拦截器

定义一个拦截器实现HandlerInterceptor接口,或者继承HandlerInterceptorAdapter,重写preHandle()方法


@Component
public class GatewayRequestInterceptor implements HandlerInterceptor {

    private static final Logger log = LoggerFactory.getLogger(GatewayRequestInterceptor.class);


    public GatewayRequestInterceptor() {
    }


    /**
     * 在请求处理之前进行调用(Controller方法调用之前),编写请求处理之前的校验逻辑
     * return true,请求将会继续执行后面的操作
     * return false,请求被拦截,将不会请求后续的操作
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }
}

5. 拦截器链

可以在拦截器具体实现的第一步【配置拦截器】中添加多个自定义拦截器。


@Configuration
public class AuthConfig implements WebMvcConfigurer {

    @Autowired
    private GatewayRequestInterceptor gatewayRequestInterceptor;

    @Autowired
    private GatewayLoginInterceptor gatewayLoginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //拦截器1、注册gatewayLoginInterceptor拦截器(gatewayLoginInterceptor是我们自己自定义的拦截器类)
        registry.addInterceptor(gatewayLoginInterceptor);
        //拦截器2、注册gatewayRequestInterceptor拦截器(gatewayRequestInterceptor是我们自己自定义的拦截器类)
        registry.addInterceptor(gatewayRequestInterceptor);
    }
}

<think>好的,我现在需要详细介绍Spring MVC拦截器及其使用。首先,我得回忆一下自己对Spring MVC拦截器的理解,确保没有遗漏关键点。 拦截器,Interceptor,是Spring MVC中用于在请求处理的不同阶段执行操作的组件。类似过滤器,但更细粒度,针对Controller的请求。记得它有三个主要方法:preHandle、postHandle、afterCompletion。这三个方法分别在处理前、处理后和完成后执行。需要详细说明每个方法的作用和时机。 接下来,要说明如何创建拦截器。用户需要实现HandlerInterceptor接口,或者继承HandlerInterceptorAdapter(虽然可能过时了,现在Spring 5可能推荐直接实现接口)。要给出一个简单的例子,比如日志拦截器,记录请求开始和结束时间,或者权限检查的例子。 然后,配置拦截器的方式。在Spring MVC的配置类中,通过实现WebMvcConfigurer接口,重写addInterceptors方法,添加自定义的拦截器,并指定拦截的路径和排除的路径。例如,使用registry.addInterceptor(new LogInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");这样的代码。 还需要注意拦截器的执行顺序,如果有多个拦截器,它们的preHandle按配置顺序执行,postHandle和afterCompletion则相反。这点很重要,用户可能会遇到执行顺序问题,需要解释清楚。 另外,要提到拦截器的应用场景,比如日志记录、权限验证、性能监控、事务管理、国际化处理等。每个场景可以举个小例子,说明如何使用对应的拦截方法。 可能需要注意的常见问题,例如拦截器与过滤器的区别,拦截器是否能修改请求参数,或者如何处理响应数据。还有,在preHandle返回false时,后续处理会被中断,需要说明这种情况的应用,比如权限验证失败时跳转到登录页。 还要确保代码示例正确,符合当前Spring的版本。比如,现在可能更推荐使用实现WebMvcConfigurer的Java配置方式,而不是XML配置。但用户可能两种都需要,不过现在主流是Java配置,所以重点放在上面。 检查是否有遗漏的部分,比如拦截器的注册方式、路径匹配模式、排除特定路径、多个拦截器的顺序控制。同时,确保提到拦截器可以访问处理器方法的上下文,比如ModelAndView对象,但afterCompletion在渲染视图之后执行,适合资源清理操作。 最后,总结一下使用步骤:创建拦截器类,实现接口并重写方法;配置拦截器,注册并设置拦截路径;测试验证拦截器的效果。可能还需要提醒用户注意拦截器的执行流程,避免在拦截器中做耗时操作影响性能,或者循环拦截的问题。 现在把这些内容组织成结构清晰的回答,分步骤说明,并给出代码示例。确保术语正确,比如HandlerInterceptor接口的正确拼写,方法名的正确性。可能还需要指出在Spring Boot中的配置方式是否有所不同,但一般来说,配置类的方式是通用的。 确认没有违反系统级指令,比如数学公式的使用,但这个问题不涉及数学内容,所以可能不需要。但其他如中文回答、结构清晰等必须遵守。检查是否有错别字,逻辑是否通顺,用户是否能按照步骤实现拦截器。</think>### Spring MVC拦截器详解及使用步骤 --- #### 一、拦截器核心概念 **拦截器(Interceptor)** 是Spring MVC框架中用于在请求处理的不同阶段插入自定义逻辑的组件。它作用于Controller层,可拦截HTTP请求并在以下三个关键节点执行操作: | 方法名 | 执行时机 | 返回值作用 | |-----------------|---------------------------------|----------------------------| | `preHandle` | Controller方法执行前 | `true`放行,`false`终止流程 | | `postHandle` | Controller方法执行后,视图渲染前 | 修改ModelAndView对象 | | `afterCompletion` | 视图渲染完成后 | 资源清理(如关闭流) | --- #### 二、拦截器与过滤器的区别 | 特性 | 拦截器(Interceptor) | 过滤器(Filter) | |--------------|-----------------------------------|-------------------------------| | 作用范围 | Spring MVC框架内 | Servlet规范,所有Web请求 | | 依赖关系 | 依赖Spring容器 | 不依赖Spring | | 控制粒度 | 针对Controller请求 | 所有HTTP请求 | | 获取上下文 | 可通过`HandlerMethod`获取方法信息 | 仅能获取Servlet API对象 | --- #### 三、实现自定义拦截器 **步骤1:创建拦截器类** ```java public class AuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 示例:检查用户登录状态 HttpSession session = request.getSession(); if (session.getAttribute("user") == null) { response.sendRedirect("/login"); return false; // 拦截请求 } return true; // 放行 } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { // 可添加全局模型数据 modelAndView.addObject("version", "1.0.0"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { // 记录请求完成时间 long startTime = (Long) request.getAttribute("startTime"); System.out.println("请求耗时:" + (System.currentTimeMillis() - startTime) + "ms"); } } ``` **步骤2:配置拦截器Java Config方式)** ```java @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new AuthInterceptor()) .addPathPatterns("/**") // 拦截所有路径 .excludePathPatterns("/login", "/static/**"); // 排除登录页和静态资源 registry.addInterceptor(new LogInterceptor()).order(1); // 设置多个拦截器顺序 } } ``` --- #### 四、拦截器执行流程 假设配置了两个拦截器 **Interceptor1** 和 **Interceptor2**: 1. **preHandle** 执行顺序:Interceptor1 → Interceptor2 2. **postHandle** 执行顺序:Interceptor2 → Interceptor1 3. **afterCompletion** 执行顺序:Interceptor2 → Interceptor1 --- #### 五、典型应用场景 1. **身份验证** ```java public boolean preHandle(...) { if (!isAuthenticated(request)) { response.sendError(401, "Unauthorized"); return false; } return true; } ``` 2. **日志记录** ```java public void afterCompletion(...) { log.info("[{}] {} - {}ms", request.getMethod(), request.getRequestURI(), System.currentTimeMillis() - startTime); } ``` 3. **性能监控** ```java public boolean preHandle(...) { request.setAttribute("startTime", System.currentTimeMillis()); return true; } ``` 4. **全局数据注入** ```java public void postHandle(...) { modelAndView.addObject("currentUser", getCurrentUser()); } ``` --- #### 六、注意事项 1. **路径匹配规则** - `/**` 匹配所有路径(含子路径) - `/api/*` 仅匹配单层路径 - `/admin/**` 匹配/admin下的所有层级 2. **避免循环拦截** 不要配置拦截器拦截自身的错误页面(如`/error`) 3. **性能优化** 在`preHandle`中优先进行轻量级检查,耗时操作建议异步处理 --- 通过合理使用拦截器,可以实现横切关注点(Cross-Cutting Concerns)的统一处理,提升代码的可维护性。实际开发中建议结合具体业务需求设计拦截逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值