成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

過濾器Filter和攔截器Interceptor的聯系和區別

開發 前端
本文將對攔截器Interceptor進行簡單講解,并通過幾個例子對它們的差異進行簡要分析。

本文將對攔截器Interceptor進行簡單講解,并通過幾個例子對它們的差異進行簡要分析。

攔截器Interceptor簡介

一個應用中可以定義多個攔截器,spring在項目啟動時,會將這些攔截器注冊進來,并按照默認規則進行排序。如果是自定義的攔截器,可手動設置攔截器調用的先后順序。

各攔截器是鏈式調用,一個請求可以觸發多個攔截器,每個攔截器的調用會按照它加載到spring中的順序依次執行。

攔截器中有3個方法,功能如下:

  • preHandle:該方法在調用Controller方法或獲取靜態資源前被調用(靜態資源包括html、js等)。
  • postHandle:該方法在調用Controller方法或獲取靜態資源后,但是視圖還沒有被渲染前調用。
  • afterCompletion:該方法在視圖渲染后進行調用,主要用來清除資源。

自定義攔截器Interceptor 

  1. public class MyInterceptor implements HandlerInterceptor { 
  2.     @Override 
  3.     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 
  4.         System.out.println("調用preHandle"); 
  5.         return true
  6.     } 
  7.  
  8.     @Override 
  9.     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { 
  10.         System.out.println("調用postHandle"); 
  11.     } 
  12.  
  13.     @Override 
  14.     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { 
  15.         System.out.println("調用afterCompletion"); 
  16.     } 

注冊自定義攔截器Interceptor

編寫配置類并實現WebMvcConfigurer接口。 

  1. @Configuration 
  2. public class MyWebConfig implements WebMvcConfigurer { 
  3.     @Override 
  4.     public void addInterceptors(InterceptorRegistry registry) { 
  5.         registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**"); 
  6.     } 

過濾器Filter和攔截器Interceptor區別

過濾器和攔截器都可以實現例如編碼設置、日志記錄、權限控制等功能,但是二者還是有很多區別的。

(1)實現原理不同

Filter是基于函數回調實現的:

每個自定義過濾器都會實現一個doFilter()方法,這個方法有一個關鍵參數FilterChain。它是一個回調接口,ApplicationFilterChain是它的具體實現類,該類內部也有一個doFilter()方法,這個方法就是回調方法(ps:可以理解為方法遞歸調用,查看源碼比較容易理解)。

假設有2個濾器,調用流程圖如下(ps:畫的比較抽象): 

兩個過濾器執行流程 

Interceptor是基于反射實現的:

為什么說攔截器是基于反射實現的呢?個人理解在攔截器內部的三個方法中,都有一個共同的參數handler,這個參數里包含的信息比較豐富。包含該請求所對應的方法、方法所在的Controller、方法參數等信息,而這些信息都是spring通過反射加載進來的。正是由于這些豐富的參數,使得攔截的功能相比過濾器功能更強大。 

 handler參數信息 

(2)使用范圍不同

過濾器Filter實現了javax.servlet.Filter接口,也就是說過濾器的使用要依賴于Tomcat等容器,所以它只能在web程序中使用。

攔截器Interceptor實現了

org.springframework.web.servlet接口,它是由Spring容器進行管理,并不依賴Tomcat等容器,既可以應用在web程序中,也可以應用在非web程序中。

(3)觸發時機不同

過濾器Filter是在請求進入Tomcat等容器后,servlet處理之前進行調用的。

攔截器Interceptor是在請求進入servlet后,執行Controller之前進行調用的。

(4)攔截范圍不同

過濾器Filter幾乎可以攔截所有進入容器的請求。

攔截器Interceptor只會對Controller請求或訪問static目錄下的靜態資源請求起作用。

(5)初始化時機不同

過濾器Filter是隨著Tomcat等web容器啟動時而進行初始化。

攔截器Interceptor時隨著spring啟動而進行初始化。

過濾器和攔截器如何注入依賴服務

在實際開發中,當使用到過濾器或攔截器時,難免會引入一些依賴的service服務。下面就通過例子進行簡要說明:

Filter依賴service:直接采用注解@Autowired即可。 

  1. @WebFilter(urlPatterns = {"/user/*"}) 
  2. @Log4j2 
  3. public class MyFilter implements Filter { 
  4.     @Autowired 
  5.     private UserService userService; 
  6.      
  7.     @Override 
  8.     public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { 
  9.         HttpServletRequest httpServletRequest = (HttpServletRequest) request; 
  10.         log.info("Filter獲取到請求地址:" + httpServletRequest.getServletPath()); 
  11.         filterChain.doFilter(request, response); 
  12.  
  13.         HttpServletResponse httpServletResponse = (HttpServletResponse) response; 
  14.         log.info("Filter獲取到響應類型:" + httpServletResponse.getContentType()); 
  15.     } 
  16.  
  17.     @Override 
  18.     public void init(FilterConfig filterConfig) throws ServletException { 
  19.         System.out.println("Filter隨著項目的啟動而啟動,只初始化一次"); 
  20.     } 
  21.  
  22.     @Override 
  23.     public void destroy() { 
  24.         System.out.println("Filter隨著web項目的停止而銷毀,完成資源回收"); 
  25.     } 

Interceptor依賴service:直接采用注解@Autowired,但是在將攔截器注入到spring容器中時,不能自己通過new來進行創建。需要將攔截器當做一個普通的bean注入到spring容器中,這樣就可以將service注入到攔截器中。 

  1. public class MyInterceptor implements HandlerInterceptor { 
  2.     @Autowired 
  3.     private UserService userService; 
  4.      
  5.     @Override 
  6.     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 
  7.         System.out.println("調用preHandle"); 
  8.         return true
  9.     } 
  10.  
  11.     @Override 
  12.     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { 
  13.         System.out.println("調用postHandle"); 
  14.     } 
  15.  
  16.     @Override 
  17.     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { 
  18.         System.out.println("調用afterCompletion"); 
  19.     } 

 

  1. @Configuration 
  2. public class MyWebConfig implements WebMvcConfigurer { 
  3.  
  4.     @Bean 
  5.     public MyInterceptor getMyInterceptor(){ 
  6.         return new MyInterceptor(); 
  7.     } 
  8.  
  9.     @Override 
  10.     public void addInterceptors(InterceptorRegistry registry) { 
  11.         // getMyInterceptor()這種注冊方式可以在攔截器里注入bean 
  12.         registry.addInterceptor(getMyInterceptor()).addPathPatterns("/**"); 
  13.         // 這種注冊方式由于是自己new出來的,所以在攔截器里注冊的bean都為null 
  14.         registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/**"); 
  15.     } 

過濾器和攔截器如何指定加載順序

(1)Filter:需要通過配置類指定加載順序,值越小,越先執行。采用@WebFilter無法指定順序。 

  1. @Bean 
  2. public FilterRegistrationBean myFilter(){ 
  3.     MyFilter myFilter = new MyFilter(); 
  4.     FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(myFilter); 
  5.     filterRegistrationBean.setUrlPatterns(Arrays.asList("/user/*")); 
  6.     filterRegistrationBean.setOrder(2); 
  7.     return filterRegistrationBean; 

(2)Interceptor:需要通過配置類指定加載順序,值越小,越先執行。 

  1. @Configuration 
  2. public class MyWebConfig implements WebMvcConfigurer { 
  3.     @Override 
  4.     public void addInterceptors(InterceptorRegistry registry) { 
  5.         // getMyInterceptor()這種注冊方式可以在攔截器里注入bean 
  6.         registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").order(1); 
  7.         // 這種注冊方式由于是自己new出來的,所以在攔截器里注冊的bean都為null 
  8.         registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/**").order(2); 
  9.     } 

過濾器Filter和攔截器Interceptor使用場景

二者相比攔截器功能更強大些,Filter能做的事情,它都能做,而且可以在請求前,請求后執行,比較靈活。Filter主要用來設置字符編碼、過濾敏感詞匯和URL級別的簡單權限控制。如果需要記錄比較詳細的信息或比較復雜的權限管理,還是建議用攔截器實現。

拓展

Servlet和Controller的區別是什么?

使用Servlet可以收集來自網頁表單的用戶輸入,還可以動態創建網頁。DispatcherServlet是SpringMVC中唯一的Servlet,Servlet容器(Tomcat)把所有的請求都轉發到DispatcherServlet,然后通過HandlerMapping把請求路由到具體的Controller中。因此,Controller只是一個普通的Java Bean。

 

責任編輯:未麗燕 來源: 今日頭條
相關推薦

2023-02-20 07:19:14

2023-05-29 07:36:04

Java過濾器攔截器

2020-06-04 07:45:07

過濾器和攔截器

2020-09-14 12:46:25

過濾器攔截器Filter

2025-05-12 04:00:00

2021-11-03 17:04:11

攔截器操作Servlet

2024-01-17 08:56:31

2016-12-07 09:56:13

JavaFilter過濾器

2024-11-04 08:45:48

布隆過濾器元數據指紋值

2024-01-08 08:33:53

AOPSpring攔截器

2025-05-12 18:49:52

2011-01-12 19:31:54

IP FilterUnix數據包過濾器

2022-03-21 08:31:07

布隆過濾器Redis過濾器原理

2022-05-13 08:23:07

Zuul微服務Zuul過濾器

2023-09-15 11:26:16

2009-06-24 16:00:00

2021-07-05 15:22:03

Servlet過濾器客戶端

2009-06-22 11:28:00

Filter結構建立過濾器

2023-09-05 08:58:07

2024-01-05 09:04:35

隆過濾器數據結構哈希函數
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品欧美一区二区 | 日韩av一二三区 | 在线欧美视频 | 久久精品国产一区二区三区不卡 | 91精品久久久久久久久久 | 91在线观看免费视频 | 丝袜美腿av | 99精品久久久久久 | 欧美一级二级三级 | www成人免费 | 91se在线| 91美女在线观看 | h视频在线免费 | 亚洲精品视频在线播放 | 一区二区中文字幕 | 精品美女在线观看视频在线观看 | 国产日韩精品一区二区三区 | 亚洲免费观看视频 | 欧美中文字幕在线观看 | 在线国产中文字幕 | 亚洲欧美在线视频 | 成年无码av片在线 | 久久国 | 亚洲一区免费 | 日韩中文字幕 | 中文字幕精品视频 | 韩日一区二区三区 | 成人精品一区 | 91久久久久久久久久久 | 欧美日韩一区二区电影 | 久久久久久999| 一区二区中文字幕 | 日韩中文字幕视频在线观看 | 久久综合影院 | 91传媒在线观看 | 观看av| 波多野结衣电影一区 | 欧美成人激情 | 亚洲成av人影片在线观看 | 亚洲大片在线观看 | 久久激情视频 |