如何配置并使用SpringBoot中的拦截器?

2026-05-25 23:441阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1296个文字,预计阅读时间需要6分钟。

如何配置并使用SpringBoot中的拦截器?

目录 + 1. 配置拦截器 + 2. 小Demo + 1. 自定义拦截器类LoginInterceptor + 2. 将拦截器注册到容器中 + 3. 原理解析 + 1. 配置拦截器及整体步骤:+ 编写一个自定义拦截器类实现接口HandlerInterceptor + 实现接口中的方法进行拦截逻辑

目录
  • 1. 配置拦截器
  • 2. 一个小 Demo
    • 1. 自定义拦截器类—LoginInterceptor
    • 2. 将拦截器注册到容器中
  • 3. 原理分析

    1. 配置拦截器

    具体步骤:

    编写一自定义拦截器类实现接口 HandlerInterceptor

    HandlerInterceptor 接口: 可在三处进行拦截——目标方法执行之前、目标方法执行完成、页面渲染以后拦截

    public interface HandlerInterceptor { default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { } }

    将拦截器注册到容器中,实现 WebMvcConfigurer 中的 addInteraptor,然后将自定义拦截器注册到拦截器中

    指定拦截器规则 —— 拦截所有 '/**' ,静态资源也会被拦截

    如何配置并使用SpringBoot中的拦截器?

    解决静态资源同时被拦截问题:

    • addPathPatterns中精确指定精确需要拦截资源
    • excludePathPatterns 中指定排除静态资源

    可在 application.properties 文件中指定静态资源统一前缀,方便排除静态资源

    spring.mvc.static-path-pattern=/static/**

    2. 一个小 Demo

    实现未登录用户不能访问除登录页外其他页面的小Demo

    1. 自定义拦截器类—LoginInterceptor

    自定义登录拦截器,实现检测到用户未登录,则拦截用户对其他资源的访问,并返回到登录页面

    package com.wanqing.admin.interceptor; import lombok.extern.slf4j.Slf4j; import org.apache.catalina.Session; import org.springframework.lang.Nullable; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /* 登录检查 */ @Slf4j // lombok 提供的功能 public class LoginInterceptor implements HandlerInterceptor { // 目标方法执行之前 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("拦截的路径是{}", request.getRequestURI()); // 登录检查逻辑 HttpSession session = request.getSession(); Object loginUser = session.getAttribute("loginUser"); if(loginUser != null){ return true; // 放行 } // 拦截住,重定向到登录页面 request.setAttribute("msg", "未登录不允许访问"); request.getRequestDispatcher("/").forward(request, response); // 转发到当前请求 return false; } // 目标方法执行之后 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } // 页面渲染完成之后 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { } }

    2. 将拦截器注册到容器中

    通过下列方法,将拦截器注册到容器中,并配置好要拦截的路径和要放行的路径。本次 demo 中若未登录则所有路径都拦截,只放行登录页面

    package com.wanqing.admin.config; import com.wanqing.admin.interceptor.LoginInterceptor; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class AdminWebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { // 在拦截器的注册中心里,添加 Login 拦截器 registry.addInterceptor(new LoginInterceptor()) .addPathPatterns("/**") //所有请求都被拦截,静态资源也被拦截 .excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**"); // 放行的请求 } }

    3. 原理分析

    1. 根据当前请求,找到HandlerExecutionChainand,即得到可以处理请求的 Handler,以及 Handler 的所有拦截器

    处理器执行链 :

    2. 先顺序执行所有拦截器的preHandle方法

    • 如果返回为true执行下一个拦截器的preHandle;
    • 若为 false,直接倒叙执行所有已经执行了的拦截器的 afterCompletion 方法

    Step into:

    if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; }

    拦截器方法执行 源码分析:

    HandlerExecutionChain.class

    —— 顺序执行所有拦截器的preHandle方法

    for(int i = 0; i < this.interceptorList.size(); this.interceptorIndex = i++) { HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i); if (!interceptor.preHandle(request, response, this.handler)) { this.triggerAfterCompletion(request, response, (Exception)null); return false; } }

    —— 倒叙执行所有已经执行了的拦截器的 afterCompletion 方法

    void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) { for(int i = this.interceptorIndex; i >= 0; --i) { HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i); try { interceptor.afterCompletion(request, response, this.handler, ex); } catch (Throwable var7) { logger.error("HandlerInterceptor.afterCompletion threw exception", var7); } } }

    3. 如果任何一个拦截器返回 false,直接跳出不执行目标方法

    4. 所有拦截器都返回 true,执行目标方法

    5. 目标方法执行后,倒叙执行所有拦截器的 postHandle 方法

    6. 前面的步骤有任何异常都会直接触发 afterCompletion 方法

    7. 页面成果渲染完成之后,也会倒叙触发 afterCompletion 方法

    图解:

    到此这篇关于SpringBoot拦截器的配置使用介绍的文章就介绍到这了,更多相关SpringBoot拦截器内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!

    本文共计1296个文字,预计阅读时间需要6分钟。

    如何配置并使用SpringBoot中的拦截器?

    目录 + 1. 配置拦截器 + 2. 小Demo + 1. 自定义拦截器类LoginInterceptor + 2. 将拦截器注册到容器中 + 3. 原理解析 + 1. 配置拦截器及整体步骤:+ 编写一个自定义拦截器类实现接口HandlerInterceptor + 实现接口中的方法进行拦截逻辑

    目录
    • 1. 配置拦截器
    • 2. 一个小 Demo
      • 1. 自定义拦截器类—LoginInterceptor
      • 2. 将拦截器注册到容器中
    • 3. 原理分析

      1. 配置拦截器

      具体步骤:

      编写一自定义拦截器类实现接口 HandlerInterceptor

      HandlerInterceptor 接口: 可在三处进行拦截——目标方法执行之前、目标方法执行完成、页面渲染以后拦截

      public interface HandlerInterceptor { default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { } }

      将拦截器注册到容器中,实现 WebMvcConfigurer 中的 addInteraptor,然后将自定义拦截器注册到拦截器中

      指定拦截器规则 —— 拦截所有 '/**' ,静态资源也会被拦截

      如何配置并使用SpringBoot中的拦截器?

      解决静态资源同时被拦截问题:

      • addPathPatterns中精确指定精确需要拦截资源
      • excludePathPatterns 中指定排除静态资源

      可在 application.properties 文件中指定静态资源统一前缀,方便排除静态资源

      spring.mvc.static-path-pattern=/static/**

      2. 一个小 Demo

      实现未登录用户不能访问除登录页外其他页面的小Demo

      1. 自定义拦截器类—LoginInterceptor

      自定义登录拦截器,实现检测到用户未登录,则拦截用户对其他资源的访问,并返回到登录页面

      package com.wanqing.admin.interceptor; import lombok.extern.slf4j.Slf4j; import org.apache.catalina.Session; import org.springframework.lang.Nullable; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /* 登录检查 */ @Slf4j // lombok 提供的功能 public class LoginInterceptor implements HandlerInterceptor { // 目标方法执行之前 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("拦截的路径是{}", request.getRequestURI()); // 登录检查逻辑 HttpSession session = request.getSession(); Object loginUser = session.getAttribute("loginUser"); if(loginUser != null){ return true; // 放行 } // 拦截住,重定向到登录页面 request.setAttribute("msg", "未登录不允许访问"); request.getRequestDispatcher("/").forward(request, response); // 转发到当前请求 return false; } // 目标方法执行之后 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } // 页面渲染完成之后 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { } }

      2. 将拦截器注册到容器中

      通过下列方法,将拦截器注册到容器中,并配置好要拦截的路径和要放行的路径。本次 demo 中若未登录则所有路径都拦截,只放行登录页面

      package com.wanqing.admin.config; import com.wanqing.admin.interceptor.LoginInterceptor; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class AdminWebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { // 在拦截器的注册中心里,添加 Login 拦截器 registry.addInterceptor(new LoginInterceptor()) .addPathPatterns("/**") //所有请求都被拦截,静态资源也被拦截 .excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**"); // 放行的请求 } }

      3. 原理分析

      1. 根据当前请求,找到HandlerExecutionChainand,即得到可以处理请求的 Handler,以及 Handler 的所有拦截器

      处理器执行链 :

      2. 先顺序执行所有拦截器的preHandle方法

      • 如果返回为true执行下一个拦截器的preHandle;
      • 若为 false,直接倒叙执行所有已经执行了的拦截器的 afterCompletion 方法

      Step into:

      if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; }

      拦截器方法执行 源码分析:

      HandlerExecutionChain.class

      —— 顺序执行所有拦截器的preHandle方法

      for(int i = 0; i < this.interceptorList.size(); this.interceptorIndex = i++) { HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i); if (!interceptor.preHandle(request, response, this.handler)) { this.triggerAfterCompletion(request, response, (Exception)null); return false; } }

      —— 倒叙执行所有已经执行了的拦截器的 afterCompletion 方法

      void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) { for(int i = this.interceptorIndex; i >= 0; --i) { HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i); try { interceptor.afterCompletion(request, response, this.handler, ex); } catch (Throwable var7) { logger.error("HandlerInterceptor.afterCompletion threw exception", var7); } } }

      3. 如果任何一个拦截器返回 false,直接跳出不执行目标方法

      4. 所有拦截器都返回 true,执行目标方法

      5. 目标方法执行后,倒叙执行所有拦截器的 postHandle 方法

      6. 前面的步骤有任何异常都会直接触发 afterCompletion 方法

      7. 页面成果渲染完成之后,也会倒叙触发 afterCompletion 方法

      图解:

      到此这篇关于SpringBoot拦截器的配置使用介绍的文章就介绍到这了,更多相关SpringBoot拦截器内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!