Spring Boot-攔截器的使用


一、使用場景

比如對特定的URL檢查用戶是否登錄,打印處理用戶請求耗時的時間等,可以用攔截器來實現。


二、攔截器使用

定義攔截器,需要實現 HandlerInterceptor 接口,接口中有3個方法

  • preHandle:在DispatcherServlet處理請求執行之前被調用
  • postHandle:在DispatcherServlet處理請求執行完成后,生成視圖之前被調用(還未渲染頁面)
  • afterCompletion:在DispatcherServlet處理請求執行完成后,且已生成視圖被調用,可以用於清除資源(已渲染了頁面)

)2.1 創建自定義攔截器 MyInterceptor  類

@Slf4j
public class MyInterceptor implements HandlerInterceptor {

    /**
     * 定義攔截器:需要實現 HandlerInterceptor 接口
     *
     * HandlerInterceptor接口中有3個方法
     * 1.preHandle:在業務處理器處理請求之前被調用
     * 2.postHandle:在業務處理器處理請求執行完成后,生成視圖之前執行(還未渲染頁面))
     * 3.afterCompletion:在DispatcherServlet完全處理完請求后被調用,可用於清理資源等。返回處理(已經渲染了頁面)
     */

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        String methodName = method.getName();
        log.info("===攔截到了方法:{},在該方法執行之前執行===", methodName);

        // 判斷用戶有沒有登陸,一般登陸后的用戶都有一個對應的token
        String token = request.getParameter("token");
        if (StringUtils.isEmpty(token)) {
            log.info("用戶沒有登陸,沒有執行權限......請登陸");
            return false;
        }

        // 通過方法,可以獲取該方法上的自定義注解,然后通過注解來判斷該方法是否要被攔截
        // @UnInterceptor 自定義注解,不被攔截
        UnInterceptor unInterceptor = method.getAnnotation(UnInterceptor.class);
        if (null == unInterceptor) {
            return false;
        }

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("執行完方法之后進行(Controller方法調用之后),但是此時還沒有進行視圖渲染");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("整個請求都處理完畢,DispatcherServlet也渲染了對應的視圖,此時可以做一些清理的工作等等");
    }
}

)2.2 創建攔截器配置類,實現 WebMvcConfigurer 接口,對所有請求由 MyInterceptor 類進行攔截

@Configuration
public class MyInterceptorConfig implements WebMvcConfigurer {

    /**
     * 解決靜態資源被攔截問題
     *
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 實現WebMvcConfigurer不會導致靜態資源被攔截
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
    }
}

)2.3 創建controller類,接收請求

@Controller
@RequestMapping("/interceptor")
public class InterceptorController {

    @GetMapping("/test")
    public String test() {
        return "hello";
    }

    @UnInterceptor
    @GetMapping("/test1")
    @ResponseBody
    public String test1() {
        return "不被攔截";
    }
}

)2.4 創建 hello.html 頁面,用於頁面返回渲染


三、測試

)3.1 對於 token 校驗測試。在 MyInterceptor 類中的 preHandle 方法中注釋 @UnInterceptor 校驗的代碼,

 訪問 localhost:8080/interceptor/test 時,會被攔截,由於沒有帶token值,執行 preHandle 方法時返回false,不會繼續往下執行

 通過 postman 表單請求設置 token 值,再次請求

測試結果如下,可以看到 MyInterceptor 類中,三個方法都已執行,且返回了 hello.html 中的頁面

)3.2 對於自定義注解校驗測試。在 MyInterceptor 類中的 preHandle 方法中注釋token校驗的代碼,放開 @UnInterceptor 的校驗代碼,

訪問 localhost:8080/interceptor/test1 可以看到 MyInterceptor 類中,三個方法都已執行

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM