予捻 发表于 2025-5-29 10:49:40

SpringBoot拦截器

一、概述

在Spring Boot中,拦截器是一种用于拦截和处理HTTP请求的机制。它是Spring框架提供的一种中间件,用于在请求到达控制器(Controller)之前或之后执行一些共享的逻辑。
Spring Boot的拦截器基于Spring MVC框架中的HandlerInterceptor接口实现。通过创建一个自定义的拦截器类并实现HandlerInterceptor接口,可以定义拦截器要执行的逻辑和行为。
二、定义拦截器

在Spring Boot中定义拦截器十分的简单,只需要创建一个拦截器类,并实现HandlerInterceptor接口即可。
HandlerInterceptor接口中定义以下3个方法,如下表:
返回值类型方法声明描述booleanpreHandle(HttpServletRequest request, HttpServletResponse response, Object handler)该方法在控制器处理请求方法前执行,其返回值表示是否中断后续操作,返回true表示继续向下执行,返回false表示中断后续操作。voidpostHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)该方法在控制器处理请求方法调用之后、解析视图之前执行,可以通过此方法对请求域中的模型和视图做进一步修改。voidafterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)该方法在视图渲染结束后执行,可以通过此方法实现资源清理、记录日志信息等工作。它接收三个参数:

[*]HttpServletRequest request: 表示当前的HTTP请求
[*]HttpServletResponse response: 表示当前的HTTP响应
[*]Object handler: 表示被拦截的处理器(一般是Controller中的方法)
三、使用拦截器

3.1 自定义拦截器

@Component
public class LoginInterceptor implements HandlerInterceptor {
    //调用目标方法之前执行的方法
    //如果返回ture表示拦截器验证成功,执行目标方法
    //如果返回false表示拦截器验证失败,不再继续执行后续业务
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                           Object handler) throws Exception {
      //用户登录判断业务
      HttpSession session = request.getSession(false);
      if (session != null && session.getAttribute("session_userinfo") != null) {
            //用户已登录
            return true;
      }
      response.setStatus(401);
      return false;
    }
}代码中的preHandle方法是拦截器的主要方法,在目标方法调用之前执行。
在preHandle方法中,首先通过request.getSession(false)获取当前请求的HttpSession对象(如果存在的话),然后判断该HttpSession对象是否为null并且是否存在名为"session_userinfo"的属性。如果这个条件成立,说明用户已经登录,可以继续执行后续的业务,于是返回true,否则验证失败,将HTTP响应的状态码设置为401,表示未授权,然后返回false,不再继续执行后续业务。
3.2 注册拦截器

@Configuration
public class MyConfig implements WebMvcConfigurer {

    //注入
    @Autowired
    private LoginInterceptor loginInterceptor;

    //将拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
      registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**") //拦截所有的 url
                .excludePathPatterns("/user/login")//排除url: /user/login (登录)
                .excludePathPatterns("/user/reg") //排除url: /user/reg   (注册)
                .excludePathPatterns("/image/**")//排除 image(图像) 文件夹下的所有文件
                .excludePathPatterns("/**/*.js")//排除任意深度目录下的所有".js"文件
                .excludePathPatterns("/**/*.css");
    }
}UserController:
@RestController
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/login")
    public String login(){
      return "login";
    }

    @RequestMapping("/index")
    public String index(){
      return "index";
    }

    @RequestMapping("/reg")
    public String reg(){
      return "reg";
    }
}在配置类中,重写了addInterceptors方法,该方法用于注册拦截器。在这里,通过调用InterceptorRegistry的addInterceptor方法来添加拦截器,并设置拦截的路径和排除的路径。
具体地,通过调用addInterceptor(loginInterceptor)来添加LoginInterceptor拦截器。然后使用addPathPatterns方法指定需要拦截的URL路径模式,这里使用"/**"表示拦截所有的URL。使用excludePathPatterns方法来排除一些特定的URL路径,这些路径不会被拦截。
"//*.js","":表示零个或多个路径段(目录或文件夹),可以匹配任意深度的目录结构。
"/*.js":表示以".js"结尾的文件名。
常见的拦截配置:
拦截路径含义举例/*拦截一级路径能拦截 /user,/login,不能拦截 /user/login/**拦截任意路径拦截所有/user/*拦截/user的下一级路径能拦截 /user/getList,不能拦截 /user/getList/1 和 /user/user/**拦截/user下的所有路径拦截/user下的所有路径,但是不能拦截 /book/getList此外拦截器不仅可以拦截项目中的URL,还可以拦截静态资源(html,图片等)。
四、执行流程


有了拦截器之后,会在调用Controller之前进行相应的业务处理,执行的流程如下图
https://img2024.cnblogs.com/blog/2745643/202505/2745643-20250514214449256-1970086426.png

[*]添加拦截器后,执行Controller的方法之前,请求会先被拦截器拦截住。
[*]执行preHandle()方法,这个方法需要返回一个布尔类型的值。
[*]如果返回true,就表示放行本次操作, 继续访问controller中的方法。
[*]如果返回false,则不会放行(controller中的方法也不会执行)。
[*]controller当中的方法执行完毕后,再回过来执行postHandle()这个方法以及afterCompletion()方法。
[*]执行完毕之后,最终给浏览器响应数据。
五、实际案例

5.1 统一访问前缀添加

所有请求地址添加test前缀:在WebMvcConfigurer接口中,configurePathMatch方法用于配置路径匹配规则。
@Configurationpublic class MyConfig implements WebMvcConfigurer {    //统一访问前缀的添加    @Override    public void configurePathMatch(PathMatchConfigurer configurer) {      configurer.addPathPrefix("test", new Predicate
页: [1]
查看完整版本: SpringBoot拦截器