Maison  >  Article  >  Java  >  Comment utiliser l'intercepteur SpringBoot

Comment utiliser l'intercepteur SpringBoot

王林
王林avant
2023-05-16 13:01:061657parcourir

Explication détaillée de HandlerInterceptor

HandlerInterceptor permet de personnaliser l'interface de workflow de la chaîne d'exécution du processeur handler. Nous pouvons personnaliser l'intercepteur pour intercepter le processeur du gestionnaire (vous pouvez le comprendre comme l'interface de la couche contrôleur), afin de pouvoir ajouter certains comportements de traitement répétitifs courants (tels que l'authentification de l'interface, la journalisation de l'interface, la surveillance des performances, etc.) sans Modifiez l’implémentation de chaque gestionnaire. 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 {
	}
}

这三个方法的执行顺序图如下:

Comment utiliser lintercepteur SpringBoot

preHandle

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

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

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

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

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

Notez que cette explication est basée sur la version SpringBoot 2.3.12.RELEASE. 🎜🎜L'interface HandlerInterceptor n'a que trois méthodes d'implémentation vides par défaut. Dans les versions inférieures, ces trois méthodes ne sont pas des méthodes par défaut, mais des méthodes abstraites. 🎜
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");
    }
}
🎜Le diagramme de séquence d'exécution de ces trois méthodes est le suivant : 🎜🎜SpringBoot interceptor Comment utiliser le pré-traitement 🎜

preHandle🎜🎜preHandle pour intercepter l'exécution d'un processeur (handler), la méthode preHandle sera dans HandlerMapping est appelé après avoir déterminé un objet gestionnaire approprié, mais avant que HandlerAdapter appelle le gestionnaire. On peut simplement comprendre que l'interface du contrôleur est exécutée avant d'être appelée. 🎜🎜Les intercepteurs sont enchaînés, c'est-à-dire exécutés les uns après les autres. Si cette méthode renvoie vrai, l'intercepteur suivant est exécuté ou le gestionnaire est exécuté directement. Si cette méthode renvoie false ou lève une exception, la chaîne d'exécution est terminée et le gestionnaire n'est plus appelé. 🎜🎜Notez que si cette méthode ne renvoie pas vrai, alors postHandle et afterCompletion ne seront pas exécutés. 🎜🎜Alors à quoi sert cette méthode ? En fait, vous pouvez effectuer un prétraitement avant l'appel de l'interface, comme la vérification des autorisations de l'utilisateur. 🎜rrreee

postHandle🎜🎜postHandle le post-traitement sera effectué après que HandlerAdapter appelle le processeur, mais après DispatcherServlet code> code> est appelé avant le rendu de la vue. Vous pouvez effectuer un traitement supplémentaire sur <code>ModelAndView ici. On peut simplement comprendre qu'il est exécuté après l'appel de l'interface du contrôleur. 🎜🎜Notez que l'ordre d'exécution de cette méthode dans la chaîne d'exécution est inversé, c'est-à-dire que l'intercepteur déclaré en premier est exécuté plus tard. 🎜

afterCompletion🎜🎜afterCompletion est exécuté après le traitement de la requête, c'est-à-dire après le rendu de la vue. Il est généralement utilisé pour nettoyer certaines ressources et coopérer avec preHandle pour calculer le temps d'exécution de l'interface, etc. 🎜🎜Notez que, comme postHandle, l'ordre d'exécution de cette méthode dans la chaîne d'exécution est également inversé, c'est-à-dire que l'intercepteur déclaré en premier est exécuté plus tard. 🎜rrreee

Enregistrer l'intercepteur🎜🎜Notez que notre intercepteur personnalisé doit être enregistré via la classe d'implémentation de WebMvcConfigurer pour prendre effet. 🎜rrreee

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer