Spring拦截器之HandlerInterceptor使用方式

 更新时间:2024年08月21日 15:09:13   作者:?abc!  
这篇文章主要介绍了Spring拦截器之HandlerInterceptor使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

概述

有时候我们需要进行一些预处理后处理,或者是拦截请求,在请求前后后做一些处理

使用Spring MVC框架,那么建议使用HandlerInterceptor,它可以类似于普通bean直接注册到Spring容器中被管理

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 {
    }
}

preHandle

在执行Handler之前(执行业务逻辑之前),根据拦截器链顺序执行

  • 每个Interceptor 的调用会依据它的声明顺序依次执行,而且最先执行的都是Interceptor 中的preHandle 方法
  • 所以可以在这个方法中进行一些前置初始化操作或者是对当前请求的一个预处理
  • 也可以在这个方法中进行一些判断来决定请求是否要继续进行下去

该方法的返回值是布尔值Boolean 类型的,

  • 当它返回为false 时,表示请求结束,后续的Interceptor 和Controller 都不会再执行;
  • 当返回值为true 时就会继续调用下一个Interceptor 的preHandle 方法,如果已经是最后一个Interceptor 的时候就会是调用当前请求的Controller 方法。

postHandle

在执行Handler成功(执行业务逻辑成功)之后,根据拦截器链倒序执行,如果前面的流程中抛出异常或者请求被拦截则不会执行!

  • 在当前所属的Interceptor 的preHandle 方法的返回值为true 时才能被调用
  • 在当前请求进行处理之后,也就是Controller 方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用,
  • 所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作
  • postHandle 方法被调用的方向跟preHandle 是相反的,也就是说先声明的Interceptor 的postHandle 方法反而会后执行

afterCompletion

在请求处理完毕之后执行,无论是否有响应视图,无论有没有通过preHandle,无论有没有抛出异常。

只会对此前放行成功(preHandle返回true)的拦截器进行倒序调用。

  • 在当前所属的Interceptor 的preHandle 方法的返回值为true 时才能被调用
  • 该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。
  • 这个方法的主要作用是用于进行资源清理工作的

使用

构建拦截器(HandlerInterceptor )

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.gildata.gup.domain.User;
import com.gildata.gup.domain.UserEncryptReset;
import com.gildata.gup.repository.UserEncryptResetRepository;

@Component // 不可少
public class xxxStateInterceptor implements HandlerInterceptor { // 必须实现HandlerInterceptor接口

    
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        // TODO Auto-generated method stub
        // ....
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        // TODO Auto-generated method stub
        return;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        // TODO Auto-generated method stub
    }
}

注册拦截器(WebMvcConfigurerAdapter )

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import com.gildata.gup.interceptor.PasswordStateInterceptor;

@Configuration // 配置
public class WebConfigfilter extends WebMvcConfigurerAdapter{
    
    @Autowired
    private XxxStateInterceptor xxxStateInterceptor ; // 实例化拦截器

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // super.addInterceptors(registry);
        // 注册自定义的拦截器passwordStateInterceptor
        registry.addInterceptor(xxxStateInterceptor)
            .addPathPatterns("/api/*") //匹配要过滤的路径
            .excludePathPatterns("/api/changeUser/*") //匹配不过滤的路径。/api/changeUser后面的所有接口不能拦截
            .excludePathPatterns("/api/getAge", "/api/getName") // /api/getAge也不能拦截,/api/getName这个接口的请求不能拦截
    }
}

两个常用方法:

  • .addPathPatterns():增加url的拦截路径,“/**”意思是所有请求都要拦截;
  • .excludePathPatterns():排除url的拦截路径,如:“/api/getAge”, “/api/getName”:意为这两个接口不做拦截;

注意

springBoot2.0以上 WebMvcConfigurerAdapter 方法过时,有两种替代方案:

  • 继承 WebMvcConfigurationSupport 类;
  • 实现 WebMvcConfigurer 接口;

但是,继承WebMvcConfigurationSupport会让Spring-boot对mvc的自动配置失效,所以 建议用实现WebMvcConfigurer接口的方式 。

所以上面的注册拦截器更改为:

@Configuration // 配置
public class WebConfigfilter implements WebMvcConfigurer{
    
    @Autowired
    private XxxStateInterceptor xxxStateInterceptor ; // 实例化拦截器

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // super.addInterceptors(registry);
        // 注册自定义的拦截器passwordStateInterceptor
        registry.addInterceptor(xxxStateInterceptor)
            .addPathPatterns("/api/*") //匹配要过滤的路径
            .excludePathPatterns("/api/changeUser/*") //匹配不过滤的路径。/api/changeUser后面的所有接口不能拦截
            .excludePathPatterns("/api/getAge", "/api/getName") // /api/getAge也不能拦截,/api/getName这个接口的请求不能拦截
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java中的OkHttpClient 工具类

    Java中的OkHttpClient 工具类

    这篇文章主要介绍了Java中的OkHttpClient工具类,具有很好的参考价值,希望杜大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • Java ExecutorService四种线程池使用详解

    Java ExecutorService四种线程池使用详解

    这篇文章主要介绍了Java ExecutorService四种线程池使用详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-02-02
  • Java实现顺时针输出螺旋二维数组的方法示例

    Java实现顺时针输出螺旋二维数组的方法示例

    这篇文章主要介绍了利用Java如何实现顺时针输出螺旋二维数组的方法示例,文中给出了详细的示例代码和注释,相信对大家具有一定的参考价值,有需要的朋友们下面来一起看看吧。
    2017-02-02
  • 一小时迅速入门Mybatis之实体类别名与多参数 动态SQL

    一小时迅速入门Mybatis之实体类别名与多参数 动态SQL

    这篇文章主要介绍了一小时迅速入门Mybatis之实体类别名与多参数 动态SQL,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • Java微服务开发之Swagger详解

    Java微服务开发之Swagger详解

    Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步
    2021-10-10
  • mybatis插入与批量插入返回ID的原理详解

    mybatis插入与批量插入返回ID的原理详解

    这篇文章主要给大家介绍了关于mybatis插入与批量插入返回ID的原理的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用mybatis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-07-07
  • java基础之标签、按钮和按钮事件简介

    java基础之标签、按钮和按钮事件简介

    本文给大家带来的是java图形界面的基础知识,简单介绍了标签、按钮和按钮事件,十分的详细,有需要的小伙伴可以参考下。
    2015-06-06
  • GSON实现Java对象的JSON序列化与反序列化的实例教程

    GSON实现Java对象的JSON序列化与反序列化的实例教程

    GSON是Google开发并开源的一个Java的JSON转换库,这里我们将来讲解GSON实现Java对象的JSON序列化与反序列化的实例教程,需要的朋友可以参考下
    2016-06-06
  • springBoot启动报错log4j冲突的解决方案

    springBoot启动报错log4j冲突的解决方案

    这篇文章主要介绍了springBoot启动报错log4j冲突的解决方案,具有很好的参考价值,希望对大家有所帮助。
    2021-07-07
  • Java并发编程Callable与Future的应用实例代码

    Java并发编程Callable与Future的应用实例代码

    这篇文章主要介绍了Java并发编程Callable与Future的应用实例代码,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01

最新评论