首頁  >  文章  >  Java  >  SpringBoot攔截器怎麼用

SpringBoot攔截器怎麼用

王林
王林轉載
2023-05-16 13:01:061699瀏覽

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

這三個方法的執行順序圖如下:

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 的實作類別進行註冊,才能生效。

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攔截器怎麼用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除