首頁 > 軟體

SpringMVC攔截器快速掌握下篇

2022-08-19 14:00:33

攔截器引數

前置處理方法

原始方法之前執行preHandle

public boolean preHandle(HttpServletRequest request,
                         HttpServletResponse response,
                         Object handler) throws Exception {
    System.out.println("preHandle");
    return true;
}
  • request:請求物件
  • response:響應物件
  • handler:被呼叫的處理器物件,本質上是一個方法物件,對反射中的Method物件進行了再包裝

使用request物件可以獲取請求資料中的內容,如獲取請求頭的Content-Type

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    String contentType = request.getHeader("Content-Type");
    System.out.println("preHandle..."+contentType);
    return true;
}

使用handler引數,可以獲取方法的相關資訊

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    HandlerMethod hm = (HandlerMethod)handler;
    String methodName = hm.getMethod().getName();//可以獲取方法的名稱
    System.out.println("preHandle..."+methodName);
    return true;
}

後置處理方法

原始方法執行後執行,如果原始方法被攔截,則不執行

public void postHandle(HttpServletRequest request,
                       HttpServletResponse response,
                       Object handler,
                       ModelAndView modelAndView) throws Exception {
    System.out.println("postHandle");
}

前三個引數和上面的是一致的。

modelAndView:如果處理器執行完成具有返回結果,可以讀取到對應資料與頁面資訊,並進行調整

因為咱們現在都是返回json資料,所以該引數的使用率不高。

完成處理方法

攔截器最後執行的方法,無論原始方法是否執行

public void afterCompletion(HttpServletRequest request,
                            HttpServletResponse response,
                            Object handler,
                            Exception ex) throws Exception {
    System.out.println("afterCompletion");
}

前三個引數與上面的是一致的。

ex:如果處理器執行過程中出現異常物件,可以針對異常情況進行單獨處理

因為我們現在已經有全域性例外處理器類,所以該引數的使用率也不高。

這三個方法中,最常用的是preHandle,在這個方法中可以通過返回值來決定是否要進行放行,我們可以把業務邏輯放在該方法中,如果滿足業務則返回true放行,不滿足則返回false攔截。

攔截器鏈設定

目前,我們在專案中只新增了一個攔截器,如果有多個,該如何設定?設定多個後,執行順序是什麼?

設定多個攔截器

建立攔截器類

實現介面,並重寫介面中的方法

@Component
public class ProjectInterceptor2 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle...222");
        return false;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle...222");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion...222");
    }
}

設定攔截器類

@Configuration
@ComponentScan({"com.nefu.controller"})
@EnableWebMvc
//實現WebMvcConfigurer介面可以簡化開發,但具有一定的侵入性
public class SpringMvcConfig implements WebMvcConfigurer {
    @Autowired
    private ProjectInterceptor projectInterceptor;
    @Autowired
    private ProjectInterceptor2 projectInterceptor2;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //設定多攔截器
        registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
        registry.addInterceptor(projectInterceptor2).addPathPatterns("/books","/books/*");
    }
}

然後我們執行程式,觀察順序:

攔截器執行的順序是和設定順序有關。就和前面所提到的運維人員進入機房的案例,先進後出。

  • 當設定多個攔截器時,形成攔截器鏈
  • 攔截器鏈的執行順序參照攔截器新增順序為準
  • 當攔截器中出現對原始處理器的攔截,後面的攔截器均終止執行
  • 當攔截器執行中斷,僅執行設定在前面的攔截器的afterCompletion操作

preHandle:與設定順序相同,必定執行

postHandle:與設定順序相反,可能不執行

afterCompletion:與設定順序相反,可能不執行。

這個順序不太好記,最終只需要把握住一個原則即可:以最終的執行結果為準

到此這篇關於SpringMVC攔截器快速掌握下篇的文章就介紹到這了,更多相關SpringMVC攔截器內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com