SpringBoot 拦截器妙用你真的了解吗

HandlerInterceptor 详解

HandlerInterceptor 允许定制 handler 处理器执行链的工作流接口。我们可以自定义拦截器用于拦截 handlers 处理器(你可以理解为 controller 层的接口),从而可以添加一些共同的重复性的处理行为(例如接口鉴权,接口日志记录,性能监控等),而不用修改每一个 handler 的实现。

注意,此基于 SpringBoot 2.3.12.RELEASE 版本讲解。

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

preHandle 前置处理,拦截一个处理器(handler)的执行,preHandle 方法会在 HandlerMapping 确定一个适当的处理器对象之后,但在 HandlerAdapter 调用处理器之前被调用。可以简单理解为 controller 接口被调用之前执行。

Intercepter 是链式的,就是一个接着一个执行。如果此方法返回 true,则会执行下一个拦截器或者直接执行处理器。如果此方法返回 false 或者抛出异常则终止执行链,也不再调用处理器。

注意,此方法如果不返回 true,那么 postHandleafterCompletion 不会被执行。

那这个方法有什么用呢?其实可以做一些接口被调用前的预处理,例如用户权限校验。

package com.chenpi;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

/**
 * @Description 用户权限验证拦截
 * @Author 陈皮
 * @Date 2021/6/27
 * @Version 1.0
 */
@Component
public class UserPermissionInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
            Object handler) {

        if (handler instanceof HandlerMethod) {

            HandlerMethod handlerMethod = (HandlerMethod) handler;

            // 获取用户权限校验注解
            UserAuthenticate userAuthenticate =
                    handlerMethod.getMethod().getAnnotation(UserAuthenticate.class);
            if (null == userAuthenticate) {
                userAuthenticate = handlerMethod.getMethod().getDeclaringClass()
                        .getAnnotation(UserAuthenticate.class);
            }
            if (userAuthenticate != null && userAuthenticate.permission()) {
                // 验证用户信息
                UserContext userContext = userContextManager.getUserContext(request);
                if (null == userContext) {
                    return false;
                }
            }
        }
        return true;
    }
}

postHandle

postHandle 后置处理,会在 HandlerAdapter 调用处理器之后,但在 DispatcherServlet 渲染视图之前被调用。可以在此对 ModelAndView 做一些额外的处理。可以简单理解为 controller 接口被调用之后执行。

注意,此方法在执行链中的执行顺序是倒着执行的,即先声明的拦截器后执行。

afterCompletion

afterCompletion 完成之后,在请求处理完之后被执行,也就是渲染完视图之后。一般用于做一些资源的清理工作,配合 preHandle 计算接口执行时间等。

注意,和 postHandle 一样,此方法在执行链中的执行顺序也是倒着执行的,即先声明的拦截器后执行。

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
                            Object handler, @Nullable Exception ex) {
    // 请求完后,清除当前线程的用户信息
    UserContextHolder.removeUserContext();
}

注册拦截器

注意,我们自定义的拦截器要通过 WebMvcConfigurer 的实现类进行注册,才能生效。

package com.yzj.ehr.common.config;

import com.yzj.ehr.common.context.UserContextResolver;
import org.springframework.stereotype.Component;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.yzj.ehr.common.interceptor.UserPermissionInterceptor;

/**
 * @Description 注册拦截器
 * @Author 陈皮
 * @Date 2021/6/27
 * @Version 1.0
 */
@Component
public class WebAppConfigurer implements WebMvcConfigurer {

    private UserPermissionInterceptor userPermissionInterceptor;

    public WebAppConfigurer(final UserPermissionInterceptor userPermissionInterceptor) {
        this.userPermissionInterceptor = userPermissionInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 匹配所有接口,排除/base/test接口
        registry.addInterceptor(userPermissionInterceptor).addPathPatterns("/**")
                .excludePathPatterns("/base/test");
    }
}

到此这篇关于SpringBoot 拦截器妙用你真的了解吗的文章就介绍到这了,更多相关SpringBoot 拦截器内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解SpringBoot 解决拦截器注入Service为空问题

    一.自定义拦截器实现 HandlerInterceptor 接口 /** * * Created by zhh on 2018/04/20. */ public class MyInterceptor implements HandlerInterceptor { @Autowired private NetworkProxyInfoService networkProxyInfoService; @Override public void afterCompletion(HttpServlet

  • 详解SpringBoot AOP 拦截器(Aspect注解方式)

    常用用于实现拦截的有:Filter.HandlerInterceptor.MethodInterceptor 第一种Filter属于Servlet提供的,后两者是spring提供的,HandlerInterceptor属于Spring MVC项目提供的,用来拦截请求,在MethodInterceptor之前执行. 实现一个HandlerInterceptor可以实现接口HandlerInterceptor,也可以继承HandlerInterceptorAdapter类,两种方法一样.这个不在本文

  • SpringBoot的拦截器中依赖注入为null的解决方法

    该项目是基于SpringBoot框架的Maven项目. 今天在拦截器中处理拦截逻辑时需要使用注解调用其他方法 并且要从配置文件中读取参数.所以我使用了以下注解: @Reference CoreRedisService redisService; @Value("${channel}") private String channel; @Value("${allowMethod}") private String allowMethod; 一个是获取接口的引用,两外两

  • 解决Springboot @WebFilter拦截器未生效问题

    问题描述 @WebFilter(filterName = "ssoFilter",urlPatterns = "/*") 未生效拦截器 解决方法 在springboot启动类上添加 @ServletComponentScan(basePackages = "full.package.path") 路径替换为@WebFilter所在包 补充知识:在spring boot中使用@WebFilter配置filter(包括排除URL) 我就废话不多说了,

  • springboot拦截器过滤token,并返回结果及异常处理操作

    1.springboot 拦截器处理过滤token,并且返回结果 import org.apache.commons.lang3.StringUtils; import org.apache.shiro.subject.Subject; import org.springframework.lang.Nullable; import org.springframework.stereotype.Component; import org.springframework.web.servlet.H

  • SpringBoot拦截器如何获取http请求参数

    1.1.获取http请求参数是一种刚需 我想有的小伙伴肯定有过获取http请求的需要,比如想 前置获取参数,统计请求数据 做服务的接口签名校验 敏感接口监控日志 敏感接口防重复提交 等等各式各样的场景,这时你就需要获取 HTTP 请求的参数或者请求body,一般思路有两种,一种就是自定义个AOP去拦截目标方法,第二种就是使用拦截器.整体比较来说,使用拦截器更灵活些,因为每个接口的请求参数定义不同,使用AOP很难细粒度的获取到变量参数,本文主线是采用拦截器来获取HTTP请求. 1.2.定义拦截器获

  • SpringBoot之HandlerInterceptor拦截器的使用详解

    前言 平常项目开发过程中,会遇到登录拦截,权限校验,参数处理,防重复提交等问题,那拦截器就能帮我们统一处理这些问题. 一.实现方式 1.1 自定义拦截器 自定义拦截器,即拦截器的实现类,一般有两种自定义方式: 定义一个类,实现org.springframework.web.servlet.HandlerInterceptor接口. 定义一个类,继承已实现了HandlerInterceptor接口的类,例如org.springframework.web.servlet.handler.Handle

  • SpringBoot快速设置拦截器并实现权限验证的方法

    一.概述 拦截器的使用场景越来越多,尤其是面向切片编程流行之后.那通常拦截器可以做什么呢? 之前我们在Agent介绍中,提到过统计函数的调用耗时.这个思路其实和AOP的环绕增强如出一辙. 那一般来说,场景如下: 函数增强:比如对一个函数进行参数检查,或者结果过滤等.甚至可以对函数就行权限认证. 性能监控:统计函数性能. 日志打点:比如在用户登录函数之前,打点统计PV等信息. 以及其他等等. 二.Spring的拦截器 无论是SpringMVC或者SpringBoot中,关于拦截器不得不提: org

  • SpringBoot 拦截器妙用你真的了解吗

    HandlerInterceptor 详解 HandlerInterceptor 允许定制 handler 处理器执行链的工作流接口.我们可以自定义拦截器用于拦截 handlers 处理器(你可以理解为 controller 层的接口),从而可以添加一些共同的重复性的处理行为(例如接口鉴权,接口日志记录,性能监控等),而不用修改每一个 handler 的实现. 注意,此基于 SpringBoot 2.3.12.RELEASE 版本讲解. HandlerInterceptor 接口只有三个默认空实

  • SpringBoot拦截器的使用小结

    总结一下SpringBoot下拦截器的使用,步骤很简单: 1.自定义自己的拦截类,拦截类需要继承HandlerInterceptor接口并实现这个接口的方法. @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { //方法调用前执行 return true;//返回

  • SpringBoot拦截器实现登录拦截的方法示例

    源码 GitHub:https://github.com/291685399/springboot-learning/tree/master/springboot-interceptor01 SpringBoot拦截器可以做什么 可以对URL路径进行拦截,可以用于权限验证.解决乱码.操作日志记录.性能监控.异常处理等 SpringBoot拦截器实现登录拦截 pom.xml: <?xml version="1.0" encoding="UTF-8"?> &

  • SpringBoot 拦截器和自定义注解判断请求是否合法

    应用场景举例: 当不同身份的用户请求一个接口时,用来校验用户某些身份,这样可以对单个字段数据进行精确权限控制,具体看代码注释 自定义注解 /** * 对比请求的用户身份是否符合 * @author liuyalong * @date 2020/9/25 16:03 */ @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface CompareUser { /** * The name

  • springboot拦截器无法注入redisTemplate的解决方法

    在工作中我们经常需要做登录拦截验证或者其他拦截认证功能,基于springboot项目下我们很容易想到结合redis做的分布式拦截,把用户登录或者需要验证的信息放到redis里面.但是在写拦截器的时候发现redisTemplate一直无法注入进来,最后查资料才发现springboot拦截器是在Bean实例化之前执行的,所以Bean实例无法注入. 先看下问题,新建一个拦截器,然后注入redisTemplate /** * @author: lockie * @Date: 2019/8/13 16:1

  • SpringBoot拦截器以及源码详析

    目录 1.拦截器是什么 2.自定义拦截器 2.1 编写拦截器 2.2 注册和配置拦截器 3.拦截器原理 3.1 找到可以处理请求的handler以及handler的所有拦截器 3.2 执行拦截器的preHandle方法 3.3 执行目标方法 3.4 执行拦截器的postHandle方法 3.5 执行拦截器的afterCompletion方法 3.6 异常处理 4.总结 1.拦截器是什么 java里的拦截器(Interceptor)是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一

  • Springboot拦截器如何获取@RequestBody参数

    Springboot拦截器获取@RequestBody参数 HttpContextUtils import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader;

  • springboot拦截器Interceptor的使用,你都了解吗

    springmvc 中的拦截器可以对请求进行判别, 在请求到达控制器之前, 把非法的请求给拦截掉 下面来说一说, 它在springboot中的使用 拦截器是可以有多个的, 对不同的 url 进行拦截 我们这个例子设想的是, 如果用户登录过, 就会用户设置一个 session , 如果session中 有user 的信息,就说明用户是登录过的 1.我们先创建一个 User 的实例对象 domain public class User { private Integer id; private St

随机推荐