玩转SpringBoot2快速整合拦截器的方法

 更新时间:2019年09月27日 09:33:07   作者:桌前明月  
这篇文章主要介绍了玩转SpringBoot2快速整合拦截器的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

概述

首先声明一下,这里所说的拦截器是 SpringMVC 的拦截器(HandlerInterceptor)。使用SpringMVC 拦截器需要做如下操作:

创建拦截器类需要实现 HandlerInterceptor

在 xml 配置文件中配置该拦截器,具体配置代码如下:

<mvc:interceptors>
 <mvc:interceptor>
 <!-- /test/** 这个是拦截路径以/test开头的所有的URL-->
 <mvc:mapping path="/**"/><!—这个是拦截所有的路径-->
 <!-- 配置拦截器类路径-->
 <bean class="cn.ljk.springmvc.controller.MyInterceptor"></bean>
 <!-- 配置不拦截器URL路径-->
 <mvc:exclude-mapping path="/fore/**"/>
 </mvc:interceptor>
</mvc:interceptors>

因为在SpringBoot 中没有 xml 文件,所以SpringBoot 为我们提供 Java Config 的方式来配置拦截器。配置方式有2种:

  1. 继承 WebMvcConfigurerAdapter (官方已经不建议使用)
  2. 实现 WebMvcConfigurer

接下来开始 SpringBoot 整合拦截器操作详细介绍!

整合拦截器实战操作

第一步:声明拦截器类

通过实现 HandlerInterceptor 来完成。具体代码如下:

public class LoginInterceptor implements HandlerInterceptor{}

第二步:实现 HandlerInterceptor 3 个拦截方法

  • preHandle:Controller逻辑执行之前进行拦截
  • postHandle:Controller逻辑执行完毕但是视图解析器还未进行解析之前进行拦截
  • afterCompletion:Controller逻辑和视图解析器执行完毕进行拦截

实际开发中 preHandle 使用频率比较高,postHandle 和 afterCompletion操作相对比较少。在下面的代码中 preHandle 方法中定义拦截所有访问项目 url 并进行日志信息记录。

postHandle 中在视图解析前进行拦截,通过 Model 再次添加数据到 Request域中。

afterCompletion 暂时没有想到使用场景,如果有使用过的场景可以在下面评论区中进行评论。

拦截器详细代码如下:

public class LoginInterceptor implements HandlerInterceptor{
 
 private Logger log = LoggerFactory.getLogger(LoginInterceptor.class);
 
 //ControllerController逻辑执行之前
 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
 log.info("preHandle....");
 String uri = request.getRequestURI();
 log.info("uri:"+ uri);
 if (handler instanceof HandlerMethod) {
  HandlerMethod handlerMethod = (HandlerMethod) handler;
  log.info("拦截 Controller:"+ handlerMethod.getBean().getClass().getName());
  log.info("拦截方法:"+handlerMethod.getMethod().getName());
 }
 
 return true;
 }
 
 //Controller逻辑执行完毕但是视图解析器还未进行解析之前
  @Override
  public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
   log.info("postHandle....");
   Map<String,Object>map=modelAndView.getModel();
 map.put("msg","postHandle add msg");
  }
  
  //Controller逻辑和视图解析器执行完毕
  @Override
  public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
   log.info("afterCompletion....");
  }
}

第三步:Java Config 的方式来配置拦截器

继承 WebMvcConfigurerAdapter 方式

通过继承 WebMvcConfigurerAdapter 并重写 addInterceptors方法,通过其参数 InterceptorRegistry 将拦截器注入到 Spring的上下文中。

另外拦截路径和不拦截的路径通过InterceptorRegistry 的 addPathPatterns 和 excludePathPatterns 方法进行设置。

继承 WebMvcConfigurerAdapter 方式官方已经不建议使用,因为官方已将 WebMvcConfigurerAdapter 标记为@Deprecated 了。

@Deprecated
public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {

继承 WebMvcConfigurerAdapter 方式具体代码如下:

@Configuration
 public class InterceptorConfigByExtendsWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter{
 
 @Bean
  public LoginInterceptor loginInterceptor(){
    return new LoginInterceptor();
  }
 
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(loginInterceptor()).addPathPatterns("/**").excludePathPatterns("/*.html");
  }
}

实现 WebMvcConfigurer 方式

通过实现 WebMvcConfigurer 接口 并实现 addInterceptors方法,其他操作和继承 WebMvcConfigurerAdapter 方式一样。具体代码如下:

@Configuration
public class InterceptorConfigByImplWebMvcConfigurer implements WebMvcConfigurer{
 
 @Bean
  public LoginInterceptor loginInterceptor(){
    return new LoginInterceptor();
  }
 @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(loginInterceptor()).addPathPatterns("/**").excludePathPatterns("/*.html");
  }
}

测试

编写普通Controller,具体代码如下:

@Controller
public class IndexController {
 
 @GetMapping("/index")
 public String index(ModelAndView modelAndView){
 
 return "index";
 }
}

在 src/main/resource 下的 templates 目录下创建 IndexController 访问页面 index.ftl, 代码如下:

<h1>${msg}</h1>

由于我这里使用的是 Freemarker 当页面使用,所以需要引入 freemarker starter依赖,具体点如下:

 <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-freemarker</artifactId>
 </dependency>

通过游览器访问 localhost:8080/sbe/index,具体访问效果如下:

如上图所示在视图解析前通过 Model 再次添加数据到 Request域中的msg 成功显示出来了!

日志输出信息如下:(拦截地址和拦截Controller 和具体方法进行日志输出)

2019-09-24 15:53:04.144  INFO 7732 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/sbe]    : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-09-24 15:53:04.145  INFO 7732 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2019-09-24 15:53:04.153  INFO 7732 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 8 ms
2019-09-24 15:53:04.155  INFO 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.LoginInterceptor  : preHandle....
2019-09-24 15:53:04.155  INFO 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.LoginInterceptor  : uri:/sbe/index
2019-09-24 15:53:04.155  INFO 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.LoginInterceptor  : 拦截 Controller:cn.lijunkui.controller.IndexController
2019-09-24 15:53:04.155  INFO 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.LoginInterceptor  : 拦截方法:index
2019-09-24 15:53:04.156  INFO 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.LoginInterceptor  : postHandle....
2019-09-24 15:53:04.161  INFO 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.LoginInterceptor  : afterCompletion....

小结

SpringBoot 2 整合拦截器和整合 Filter的操作很像,都是通过一个注册类将其注入到Spring的上下文中,只不过Filter使用的是 FilterRegistrationBean 而 拦截器使用的是 InterceptorRegistry。

个人觉得比使用 xml 配置的方式更为简单了,如果你还没有在 SpringBoot 项目中使用过拦截器,赶快来操作一下吧!

代码示例

具体代码示例请在我的GitHub 仓库 springbootexamples 中模块名为 spring-boot-2.x-interceptor 项目中进行查看

GitHub:https://github.com/zhuoqianmingyue/springbootexamples

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • SpringBoot2.6.3集成quartz的方式

    SpringBoot2.6.3集成quartz的方式

    quartz是java里头定时任务的经典开源实现,这里讲述一下如何在SpringBoot2.6.3集成quartz,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2022-02-02
  • Java多种方法实现合并多个list对象列表

    Java多种方法实现合并多个list对象列表

    Java编程中,合并多个列表对象可以通过Stream API或传统循环方式实现,使用Stream API合并时,利用flatMap方法将嵌套的List展平,再通过collect方法收集成一个新的列表,传统循环则通过创建一个空的ArrayList,并通过遍历每个列表将元素添加进去
    2024-09-09
  • spring 操作elasticsearch查询使用方法

    spring 操作elasticsearch查询使用方法

    本篇文章主要介绍了spring 操作elasticsearch使用方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • 一种类似JAVA线程池的C++线程池实现方法

    一种类似JAVA线程池的C++线程池实现方法

    线程池(thread pool)是一种线程使用模式。线程过多或者频繁创建和销毁线程会带来调度开销,进而影响缓存局部性和整体性能。这篇文章主要介绍了一种类似JAVA线程池的C++线程池实现方法,需要的朋友可以参考下
    2019-07-07
  • Java面向接口编程之简单工厂模式示例

    Java面向接口编程之简单工厂模式示例

    这篇文章主要介绍了Java面向接口编程之简单工厂模式,结合实例形式详细分析了java面向接口编程简单工厂模式的具体定义与使用方法,需要的朋友可以参考下
    2019-09-09
  • 解决PageHelper的上下文问题导致SQL查询结果不正确

    解决PageHelper的上下文问题导致SQL查询结果不正确

    主要介绍了PageHelper在使用过程中出现的分页上下文问题,并分析了可能的原因和解决方案,主要解决方案包括每次分页查询后调用`PageHelper.clearPage()`清理分页上下文,确保每次查询前正确调用`startPage`,以及避免在条件判断未执行SQL时影响后续查询
    2024-12-12
  • IDEA 中使用 Hudi的示例代码

    IDEA 中使用 Hudi的示例代码

    这篇文章主要介绍了IDEA 中使用 Hudi的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • 解决SpringBoot运行报错:找不到或无法加载主类的问题

    解决SpringBoot运行报错:找不到或无法加载主类的问题

    这篇文章主要介绍了解决SpringBoot运行报错:找不到或无法加载主类的问题,具有很好的参考价值,对大家的学习或工作有一定的参考价值,需要的朋友可以参考下
    2023-09-09
  • Java三大特性之继承详解

    Java三大特性之继承详解

    继承:就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性、相同的行为。本文将来和大家详细说说Java中的继承,需要的可以了解一下
    2022-10-10
  • Java中Collections.sort()排序方法举例详解

    Java中Collections.sort()排序方法举例详解

    很多时候都需要对一些数据进行排序的操作,这篇文章主要给大家介绍了关于Java中Collections.sort()方法举例详解的相关资料,使用Collections.sort()可以使用其sort()方法来对List、Set等集合进行排序,需要的朋友可以参考下
    2024-02-02

最新评论