SpringBoot中使用拦截器的配置详解

 更新时间:2024年01月15日 10:06:43   作者:Mu_Mu是一只小白  
这篇文章主要介绍了SpringBoot中使用拦截器的配置详解,拦截器是 AOP 的一种实现,专门拦截对动态资源的后台请求,即拦截对控制层的请 求,使用场景比较多的是判断用户是否有权限请求后台,需要的朋友可以参考下

1. 应用场景

拦截器是 AOP 的一种实现,专门拦截对动态资源的后台请求,即拦截对控制层的请 求。使用场景比较多的是判断用户是否有权限请求后台,更拔高一层的使用场景也有,比如拦截器可以 结合 websocket 一起使用,用来拦截 websocket 请求,然后做相应的处理等等。拦截器不会拦截静态 资源,Spring Boot 的默认静态目录为 resources/static,该目录下的静态页面、js、css、图片等等, 不会被拦截.

2. 定义拦截器

定义拦截器,只需要实现 HandlerInterceptor 接口, 该接口中有三个方法:

preHandle(……) 、 postHandle(……) 和 afterCompletion(……) 。

  • preHandle(……) 方法:该方法的执行时机是,当某个 url 已经匹配到对应的 Controller 中的某个方法,且在这个方法执行之前。所以 preHandle(……) 方法可以决定是否将请求放行,这是通过返回值来决定的,返回 true 则放行,返回 false 则不会向后执行。
  • postHandle(……) 方法:该方法的执行时机是,当某个 url 已经匹配到对应的 Controller 中的某个方法,且在执行完了该方法,但是在 DispatcherServlet 视图渲染之前。所以在这个方法中有个ModelAndView 参数,可以在此做一些修改动作。
  • afterCompletion(……) 方法:顾名思义,该方法是在整个请求处理完成后(包括视图渲染)执行,这时做一些资源的清理工作,这个方法只有在 preHandle(……) 被成功执行后并且返回 true才会被执行。

2.1 自定义拦截类实现HandlerInterceptor接口

public class MyInterceptor implements HandlerInterceptor {
    private Logger logger = LoggerFactory.getLogger(MyInterceptor.class);
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        String methodName = method.getName();
        logger.info("方法{}被拦截", methodName);
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        logger.info("方法被执行,但是视图还未渲染");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        logger.info("方法执行完毕,进行资源清理");
    }
}

2.2 实现WebMvcConfigurer接口进行拦截配置

实现WebMvcConfigurer的这种配置会自动过滤静态资源;

@Configuration
public class MyInterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
    }
}

省略controller类

测试结果

10:52:16.316 [http-nio-8080-exec-1] INFO  c.e.h.interceptors.MyInterceptor - 方法test被拦截
10:52:16.344 [http-nio-8080-exec-1] INFO  c.e.h.interceptors.MyInterceptor - 方法被执行,但是视图还未渲染
10:52:16.344 [http-nio-8080-exec-1] INFO  c.e.h.interceptors.MyInterceptor - 方法执行完毕,进行资源清理

定义哪些不用拦截

取消拦截操作

如果我要拦截所有 /admin 开头的 url 请求的话,需要在拦截器配置中添加这个前缀,但是 在实际项目中,可能会有这种场景出现:某个请求也是 /admin 开头的,但是不能拦截,比如 /admin/login 等等

解决方案:

1.使用excludePathPatterns("/adminUser/login")

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/adminUser/login");
    }

2.可以定义一个注解

该注解专门用来取消拦截操作,如果某个 Controller 中的方法我们 不需要拦截掉,即可在该方法上加上我们自定义的注解即可,下面先定义一个注解:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UnInterception {
}

测试

controller类

@RestController
@RequestMapping("/intercept")
public class IntercepController {

    @UnInterception
    @RequestMapping("/hello")
    public String test() {
        return "success";
    }

interceptor拦截类

   @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        String methodName = method.getName();
        if (method.getAnnotation(UnInterception.class)!=null) {
            logger.info("方法{}不被拦截", methodName);
            return true;
        }
        logger.info("方法{}被拦截", methodName);
        return false;
    }

访问 localhost:8080/intercept/hello

结果

11:34:24.648 [http-nio-8080-exec-1] INFO  c.e.h.interceptors.MyInterceptor - 方法test不被拦截
11:34:24.676 [http-nio-8080-exec-1] INFO  c.e.h.interceptors.MyInterceptor - 方法被执行,但是视图还未渲染
11:34:24.679 [http-nio-8080-exec-1] INFO  c.e.h.interceptors.MyInterceptor - 方法执行完毕,进行资源清理

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

相关文章

  • Java字符编码解码的实现详解

    Java字符编码解码的实现详解

    本篇文章介绍了,Java字符编码解码的实现详解。需要的朋友参考下
    2013-05-05
  • Java在Linux下 不能处理图形的解决办法 分享

    Java在Linux下 不能处理图形的解决办法 分享

    Java在Linux下 不能处理图形的解决办法 分享,需要的朋友可以参考一下
    2013-06-06
  • 深入理解java代码实现分治算法

    深入理解java代码实现分治算法

    分治算法是一种递归算法,它将问题划分为几个独立的子问题,然后递归地解决这些子问题,最后将子问题的解合并起来得到原问题的解,本文详细的介绍java分治算法,感兴趣的可以了解一下
    2023-09-09
  • Java数组初始化的五种方式

    Java数组初始化的五种方式

    数组是Java中最基础且常用的数据结构之一,其初始化方式多样且各具特点,本文详细讲解Java数组初始化的五种方式,分析其适用场景、优劣势对比及注意事项,帮助避免常见陷阱并提升代码质量,需要的朋友可以参考下
    2025-04-04
  • 如何调试报表插件

    如何调试报表插件

    在项目开发过程中插件调试非常的麻烦,需要修改里面的代码,编译出class,需要重新打包插件。然后把之前的删除,重新安装最新的。调试过程比较繁琐,而且不能调试,十分的不方便,这篇文章主要介绍的是调试报表插件的方法,需要的朋友可以参考下
    2015-07-07
  • eclipse如何搭建Springboot项目详解

    eclipse如何搭建Springboot项目详解

    今天带大家学习eclipse如何搭建Spring boot项目,文中有非常详细的图文解说,对正在学习java的小伙伴们有很好地帮助,需要的朋友可以参考下
    2021-05-05
  • Java OOP三大特征之封装继承与多态详解

    Java OOP三大特征之封装继承与多态详解

    本文主要讲述的是面向对象的三大特性:封装,继承,多态,内容含括从封装到继承再到多态的所有重点内容以及使用细节和注意事项,内容有点长,请大家耐心看完
    2022-07-07
  • java开发线上事故理解RocketMQ异步精髓

    java开发线上事故理解RocketMQ异步精髓

    这篇文章主要介绍了java开发线上事故理解RocketMQ异步精髓
    2022-07-07
  • SpringBoot图文并茂讲解依赖管理的特性

    SpringBoot图文并茂讲解依赖管理的特性

    一般来讲SpringBoot项目是不需要指定版本,而SSM项目是需要指定版本,SpringBoot的核心依赖就是spring-boot-starter-parent和spring-boot-starter-web两个依赖,关于这两个依赖的相关介绍具体今天小编给大家介绍下
    2022-06-06
  • Javaweb项目启动Tomcat常见的报错解决方案

    Javaweb项目启动Tomcat常见的报错解决方案

    Java Web项目启动Tomcat时可能会遇到各种错误,本文就来介绍一下Javaweb项目启动Tomcat常见的报错解决方案,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02

最新评论