1.實現攔截器 1.寫一個攔截器 繼承HandlerInterceptor preHandle: 調用時間: Controller方法處理之前【也就是路徑跳轉之前】; 執行順序: 鏈式Intercepter情況下,Intercepter按照聲明的順序一個接一個執行; 返回值: 返回值為true,則繼 ...
1.實現攔截器
1.寫一個攔截器
繼承HandlerInterceptor
preHandle:
調用時間: Controller方法處理之前【也就是路徑跳轉之前】;
執行順序: 鏈式Intercepter情況下,Intercepter按照聲明的順序一個接一個執行;
返回值: 返回值為true,則繼續執行,false中斷執行,生成時預設false;
應用場景:登陸驗證之類的
postHandle:
調用前提: preHandle返回true;
調用時間: Controller方法處理完之後,DispatcherServlet進行視圖的渲染之前,也就是說在這個方法中你可以對ModelAndView進行操作
執行順序: 鏈式Intercepter情況下,Intercepter按照聲明的順序倒著執行。
備註: postHandle雖然post打頭,但post、get方法都能處理
afterCompletion:
調用前提:preHandle返回true
調用時間:DispatcherServlet進行視圖的渲染之後
應用場景:多用於清理資源,統一日誌處理,統一異常處理
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//獲取session
HttpSession session = request.getSession();
//獲取session中的用戶
UserDTO user = (UserDTO) session.getAttribute("user");
//判斷用戶是否存在
if(user == null){
//不存在並;攔截
response.setStatus(401);
return false;
}
//存在,保存用戶到TheadLocal放行
UserHolder.saveUser(user);
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
UserHolder.removeUser();
}
}
2.開啟攔截器
WebMvcConfigurer
order:決定攔截器執行的順序
初始值都為0,不設置按照添加順序執行
添加後,最先執行的是order(0)
@Configuration
public class MVCConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.excludePathPatterns("/user/code",
"/user/login",
"/shop/**",
"/upload/**",
"/shop-type/**",
"/shop/**",
"/blog/hot",
"/voucher/**",
"/user/me"
).order(1);}
}
2.攔截器類型(有待考證)
HandlerInterceptor類: 三個方法都必須繼承
public interface HandlerInterceptor {
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception;
void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
void afterCompletion(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception;
}
多個攔截器的執行順序:
HandlerInterceptorAdapter類:可以選擇性繼承三個方法中的一個
public abstract class HandlerInterceptorAdapter implements HandlerInterceptor {
//選擇需要的方法
}
3.攔截器和spring容器的先後執行順序
4.過濾器和攔截器的區別
原文鏈接:https://blog.csdn.net/nigulasizp/article/details/125322507
1、實現原理不同 過濾器和攔截器底層實現方式大不相同,過濾器 是基於函數回調的,攔截器 則是基於Java的反射機制(動態代理)實現的。
2、使用範圍不同 我們看到過濾器 實現的是 javax.servlet.Filter 介面,而這個介面是在Servlet規範中定義的,也就是說過濾器Filter 的使用要依賴於Tomcat等容器,導致它只能在web程式中使用。 而攔截器(Interceptor) 它是一個Spring組件,並由Spring容器管理,並不依賴Tomcat等容器,是可以單獨使用的。不僅能應用在web程式中,也可以用於Application、Swing等程式中。
3、觸發時機不同 過濾器Filter是在請求進入容器後,但在進入servlet之前進行預處理,請求結束是在servlet處理完以後。攔截器 Interceptor 是在請求進入servlet後,在進入Controller之前進行預處理的,Controller 中渲染了對應的視圖之後請求結束。
4、攔截的請求範圍不同 過濾器Filter執行了兩次,攔截器Interceptor只執行了一次。這是因為過濾器幾乎可以對所有進入容器的請求起作用,而攔截器只會對Controller中請求或訪問static目錄下的資源請求起作用。
5、註入Bean情況不同 這是因為載入順序導致的問題,攔截器載入的時間點在springcontext之前,而Bean又是由spring進行管理。(所以攔截器中註入不了Bean)
6、控制執行順序不同 過濾器用@Order註解控制執行順序,通過@Order控制過濾器的級別,值越小級別越高越先執行。 攔截器預設的執行順序,就是它的註冊順序,也可以通過Order手動設置控制,值越小越先執行
Filter的執行順序在Interceptor之前,具體的流程見下圖
5.攔截器的原理
攔截器Interceptor 的攔截功能是基於Java的反射機制(動態代理)實現的。