Heim  >  Artikel  >  Java  >  So verwenden Sie den SpringBoot-Interceptor

So verwenden Sie den SpringBoot-Interceptor

王林
王林nach vorne
2023-05-16 13:01:061699Durchsuche

HandlerInterceptor Ausführliche Erklärung

HandlerInterceptor ermöglicht die Anpassung der Workflow-Schnittstelle der Ausführungskette des handler-Prozessors. Wir können den Interceptor so anpassen, dass er den Handler-Prozessor abfängt (Sie können ihn als Schnittstelle der Controller-Schicht verstehen), sodass wir einige häufige sich wiederholende Verarbeitungsverhalten (z. B. Schnittstellenauthentifizierung, Schnittstellenprotokollierung, Leistungsüberwachung usw.) ohne hinzufügen können Ändern Sie die Implementierung jedes Handlers. 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 {
	}
}

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

So verwenden Sie den SpringBoot-Interceptor

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

Beachten Sie, dass dies auf der Version SpringBoot 2.3.12.RELEASE basiert. #🎜🎜##🎜🎜#Die HandlerInterceptor-Schnittstelle verfügt nur über drei standardmäßige leere Implementierungsmethoden. In niedrigeren Versionen sind diese drei Methoden keine Standardmethoden, sondern abstrakte Methoden. #🎜🎜#
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");
    }
}
#🎜🎜#Das Ausführungssequenzdiagramm dieser drei Methoden lautet wie folgt: #🎜🎜##🎜🎜#So verwenden Sie den SpringBoot-Interceptor#🎜🎜#

preHandle#🎜🎜##🎜🎜#preHandle Bei der Vorverarbeitung wird die Ausführung eines Handlers abgefangen. Die preHandle-Methode wird aufgerufen, nachdem HandlerMapping ein geeignetes Handlerobjekt ermittelt hat, aber bevor HandlerAdapter den Prozessor aufruft. Es kann einfach verstanden werden, dass die Controller-Schnittstelle ausgeführt wird, bevor sie aufgerufen wird. #🎜🎜##🎜🎜#Intercepter wird angekettet, das heißt, einer nach dem anderen hingerichtet. Wenn diese Methode „true“ zurückgibt, wird der nächste Interceptor oder Handler direkt ausgeführt. Wenn diese Methode false zurückgibt oder eine Ausnahme auslöst, wird die Ausführungskette beendet und der Handler nicht mehr aufgerufen. #🎜🎜##🎜🎜#Beachten Sie, dass postHandle und afterCompletion nicht ausgeführt werden, wenn diese Methode nicht „true“ zurückgibt. #🎜🎜##🎜🎜#Was nützt diese Methode also? Tatsächlich können Sie vor dem Aufruf der Schnittstelle einige Vorverarbeitungen durchführen, z. B. die Überprüfung der Benutzerberechtigungen. #🎜🎜#rrreee

postHandle#🎜🎜##🎜🎜#postHandle Die Nachbearbeitung erfolgt, nachdem HandlerAdapter den Prozessor aufruft , wird aber aufgerufen, bevor DispatcherServlet die Ansicht rendert. Hier können Sie ModelAndView weiter bearbeiten. Es kann einfach verstanden werden, dass es nach dem Aufruf der Controller-Schnittstelle ausgeführt wird. #🎜🎜##🎜🎜#Beachten Sie, dass die Ausführungsreihenfolge dieser Methode in der Ausführungskette umgekehrt ist, dh der zuerst deklarierte Interceptor wird später ausgeführt. #🎜🎜#

afterCompletion#🎜🎜##🎜🎜#afterCompletion wird ausgeführt, nachdem die Anfrage verarbeitet wurde, also nachdem die Ansicht gerendert wurde. Es wird im Allgemeinen verwendet, um einige Ressourcen zu bereinigen und mit preHandle zusammenzuarbeiten, um die Ausführungszeit der Schnittstelle usw. zu berechnen. #🎜🎜##🎜🎜#Beachten Sie, dass wie bei postHandle auch die Ausführungsreihenfolge dieser Methode in der Ausführungskette umgekehrt ist, dh der zuerst deklarierte Interceptor wird später ausgeführt. #🎜🎜#rrreee

Interceptor registrieren#🎜🎜##🎜🎜#Beachten Sie, dass unser benutzerdefinierter Interceptor über die Implementierungsklasse von WebMvcConfigurer registriert werden muss . #🎜🎜#rrreee

Das obige ist der detaillierte Inhalt vonSo verwenden Sie den SpringBoot-Interceptor. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen