当前位置: 首页
编程语言
SpringMVC拦截器HandlerInterceptor接口详解

SpringMVC拦截器HandlerInterceptor接口详解

热心网友 时间:2026-06-11
转载

HandlerInterceptor是SpringMVC拦截机制核心,定义preHandle、postHandle、afterCompletion方法。preHandle预处理,返回false则拦截;postHandle在控制器执行后、视图渲染前调用;afterCompletion视图渲染后执行。多拦截器时,preHandle顺序执行,postHandle和

HandlerInterceptor

HandlerInterceptor 是 Spring MVC 中实现请求拦截的核心接口,它定义了三个关键方法,犹如三道关卡,贯穿请求处理的整个生命周期。

preHandle:该方法在控制器方法执行之前被调用。你可以把它理解为一个“安检门”,非常适合进行身份验证、权限检查等预处理操作。它的返回值决定了请求是否能继续前行:返回 true 表示通过检查,请求会被放行,接着进入下一个拦截器或控制器;返回 false 则请求在此被拦截,后续的拦截器和控制器都不会再执行。

postHandle:它在控制器方法执行完毕、但视图尚未渲染之前被调用。这是一个“后加工车间”,你可以在这里对返回的 ModelAndView 对象进行修改,例如向模型添加公共数据,或者调整视图名称。

afterCompletion:这是最后一步,在视图渲染完成之后才触发。它更像一个“清道夫”,主要用于释放资源、记录日志,或者统一处理 Exception 异常信息,非常适合执行收尾工作。

单个拦截器的实现

接下来,我们通过一个完整的实例,看看单个拦截器是如何落地实现的。

定义拦截器

首先,实现 HandlerInterceptor 接口来定义一个拦截器类:

package test;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import ja vax.servlet.http.HttpServletRequest;
import ja vax.servlet.http.HttpServletResponse;

@Slf4j
@Component
public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 预处理逻辑,如权限检查
        log.info("preHandle方法执行");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 后处理逻辑,可以修改数据模型
        log.info("postHandle方法执行");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 资源清理逻辑,比如释放资源或记录日志
        log.info("afterCompletion方法执行");
    }

}

配置拦截器

定义好拦截器后,需要告诉 Spring MVC 哪些请求应该被它拦截。这需要创建一个实现了 WebMvcConfigurer 接口的配置类,并在 addInterceptors 方法中进行注册。下面的示例将拦截器配置为拦截所有请求(即 /** 路径):

package test;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import ja vax.annotation.Resource;

@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {

    @Resource
    private MyInterceptor myInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor)
                .addPathPatterns("/**");
    }

}

测试拦截器

最后,准备一个简单的控制器来验证拦截器是否生效:

package test;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Slf4j
public class MyController {

    @GetMapping("/test")
    public String test() {
        log.info("控制器方法执行");
        return "OK";
    }
    
}

启动项目,通过 HTTP 请求访问 /test 路径,控制台会输出如下结果:

SpringMVC拦截器之HandlerInterceptor接口解读

从输出顺序可以清晰地看到拦截器的执行流程:preHandle 先执行,然后才是控制器方法,接着是 postHandle,最后是 afterCompletion

多个拦截器的实现

实际项目中,我们通常会配置多个拦截器来处理不同维度的逻辑。那么多个拦截器之间是如何协作的呢?我们来一步步拆解。

定义拦截器

先定义三个拦截器,分别命名为 MyInterceptor1MyInterceptor2MyInterceptor3。它们的代码结构相同,只是日志输出不同,以便区分执行顺序。这里以第一个为例展示:

package test;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import ja vax.servlet.http.HttpServletRequest;
import ja vax.servlet.http.HttpServletResponse;

@Slf4j
@Component
public class MyInterceptor1 implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("【我的拦截器1】preHandle方法执行");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("【我的拦截器1】postHandle方法执行");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("【我的拦截器1】afterCompletion方法执行");
    }

}
### 配置拦截器

接下来配置这些拦截器,让它们分别拦截不同的路径:/test1/test2/test3

package test;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import ja vax.annotation.Resource;

@Configuration
public class MyMultipleInterceptorConfig implements WebMvcConfigurer {

    @Resource
    private MyInterceptor1 myInterceptor1;

    @Resource
    private MyInterceptor2 myInterceptor2;

    @Resource
    private MyInterceptor3 myInterceptor3;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor1)
                .addPathPatterns("/test1");
        registry.addInterceptor(myInterceptor2)
                .addPathPatterns("/test2");
        registry.addInterceptor(myInterceptor3)
                .addPathPatterns("/test3");
    }

}

测试拦截器

在控制器中为这些路径添加对应的处理方法:

package test;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Slf4j
public class MyMultipleInterceptorTestController {

    @GetMapping("/test1")
    public String test1() {
        log.info("控制器test1方法执行");
        return "OK";
    }

    @GetMapping("/test2")
    public String test2() {
        log.info("控制器test2方法执行");
        return "OK";
    }

    @GetMapping("/test3")
    public String test3() {
        log.info("控制器test3方法执行");
        return "OK";
    }

}

现在,如果访问 /test2 这个路径,控制台输出的结果会是:

SpringMVC拦截器之HandlerInterceptor接口解读

这清楚地表明,访问某个路径时,只会触发专门为该路径配置的拦截器。这是一种精确的拦截控制策略。

多个拦截器的执行顺序

如果把多个拦截器配置为拦截同一个路径,结果又如何呢?我们修改配置,让三个拦截器都拦截 /test2 路径:

// ... 配置代码中,将三个拦截器的 addPathPatterns 都改为 "/test2" ...

再次访问 /test2,输出结果如下:

SpringMVC拦截器之HandlerInterceptor接口解读

这里有个关键点需要注意:preHandle 方法的执行顺序与我们注册拦截器的顺序一致(1 -> 2 -> 3),但 postHandleafterCompletion 方法的执行顺序却完全相反,变成了 3 -> 2 -> 1。这种“先进后出”的栈式结构,在日志处理和资源清理场景中非常常见。

某个拦截器拒绝放行的情况

如果请求在某个拦截器中被拦截(即 preHandle 返回 false),又会发生什么?我们将 MyInterceptor2preHandle 返回值改为 false

// MyInterceptor2 的 preHandle 方法中,return false;

再次访问 /test2,输出结果如下:

SpringMVC拦截器之HandlerInterceptor接口解读

从结果可以总结出几条重要规则:

  • 只要任何一个拦截器的 preHandle 返回 false,目标控制器方法就绝对不会执行。
  • 对于拦截器链中,位于“拒绝拦截器”之前的拦截器(本例中的 MyInterceptor1),它们的 preHandleafterCompletion 方法都会执行。
  • 对于那个“拒绝拦截器”本身(MyInterceptor2),它的 preHandle 会执行,但 afterCompletion 不会执行。
  • 对于“拒绝拦截器”之后的所有拦截器(MyInterceptor3),它们的方法都不会被执行。
  • 所有拦截器的 postHandle 方法都不会执行,因为控制器方法根本没被调用。

理解这个执行模型,对于调试复杂的拦截器链问题会非常有帮助。

总结

HandlerInterceptor 的三个方法形成了请求处理的前、中、后三个阶段,为我们在 Spring MVC 中实现权限控制、日志记录、数据预处理等提供了强大的支持。理解单个拦截器的配置以及多个拦截器之间的执行顺序,尤其是在异常情况下的行为,是掌握 Spring MVC 拦截器机制的关键所在。

来源:https://www.jb51.net/program/365379pay.htm

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
IDEA中SpringBoot项目热部署实现指南

IDEA中SpringBoot项目热部署实现指南

Springboot项目在IDEA中实现热部署需依次完成:开启自动编译(静态与动态编译)、启用热部署策略、引入spring-boot-devtools依赖、关闭浏览器缓存,最后启动测试即可生效,省去手动重启时间,大幅提升开发效率。

时间:2026-07-11 06:47
Java实现Excel转JSON的代码详解

Java实现Excel转JSON的代码详解

使用Java结合FreeSpire XLS库可自动将Excel转为JSON,通过读取工作表并映射为键值对,高效支持数据迁移、报表导出与系统对接,大幅提升效率并消除手动录入错误。

时间:2026-07-11 06:47
Golang高效布谷鸟过滤器多字符集字符串过滤

Golang高效布谷鸟过滤器多字符集字符串过滤

布谷鸟过滤器支持删除操作,通过指纹截断与双哈希定位实现多字符集高效过滤。指纹截断需采用fnv64a或xxhash快速哈希并取低8位,桶索引使用独立双哈希避免假阳性。并发安全需以固定数组配合sync atomic实现。

时间:2026-07-11 06:47
Java使用Poi-tl按Word模板生成动态表格

Java使用Poi-tl按Word模板生成动态表格

Poi-tl是Word导出工具,文档周全,支持多级合并表头生成。通过{{text}}、{{?var}}、{{ table}}标签处理模板,传入TableRenderData对象即可动态渲染表格。示例展示用户信息表格生成,并提供工具类消除表格首行缩进,确保格式正确。

时间:2026-07-11 06:47
Go语言微服务集成Swagger生成交互式API文档完整教程

Go语言微服务集成Swagger生成交互式API文档完整教程

在Go微服务中集成Swagger常见四大问题:swaginit初始化失败需确保存在packagemain及注释;SwaggerUI加载失败因路由映射错误或未导入docs;@Param注解必须严格遵循格式;部署后接口文档显示localhost因硬编码host,应删除或通过环境变量动态注入。

时间:2026-07-11 06:47
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 热门数据榜