過濾器,攔截器,aop區別與使用場景


1. 什么是過濾器

過濾器,顧名思義就是起到過濾篩選作用的一種事物,只不過相較於現實生活中的過濾器,這里的過濾器過濾的對象是客戶端訪問的web資源,也可以理解為一種預處理手段,對資源進行攔截后,將其中我們認為的雜質(用戶自己定義的)過濾,符合條件的放行,不符合的則攔截下來。


1.1 過濾器常見使用場景

  • 統一設置編碼
  • 過濾敏感字符
  • 登錄校驗
  • URL級別的訪問權限控制
  • 數據壓縮

1.2 springboot整合過濾器

bean注入方式
a) 編寫Filter

public class HeFilter implements Filter {
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}
	
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
		System.out.println("您已進入filter過濾器,您的請求正常,請繼續遵規則...");
		chain.doFilter(request, response);
	}
	
	@Override
	public void destroy() {
	}
}

b) 編寫Filter配置類

@Configuration
public class ServletConfig {
    
    @Bean
    public FilterRegistrationBean heFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean(new HeFilter());
        registration.addUrlPatterns("/*");
        return registration;
    }
}

注解方式

@Slf4j
@Component
// filterName就是當前類名稱,還有一個urlPattens的參數,這個參數表示要過濾的URL上的后綴名,是多參數,可以用數組表示。
@WebFilter(value = "/hello")或(filterName = "f1", urlPatterns = {"*.html","*.jsp","/hello"})
public class HelloFilter2 implements Filter {
 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
 
    }
 
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
            FilterChain filterChain) throws IOException, ServletException {
        log.info("進入到過濾器2啦");
        filterChain.doFilter(servletRequest,servletResponse);
    }
 
    @Override
    public void destroy() {
 
    }
}
在主啟動類上加@ServletComponentScan("com.pandy.blog.filters")   指明filter所在位置的包。
若有多個filter,默認根據filter類名的字母倒敘排列,且@WebFilter注解方式的過濾器優先級高於Bean注入方式配置的過濾器

1.3 Filter過濾器詳解

a) Filter是依賴於Servlet的,需要有Servlet的依賴。
b) init() 在容器初始化時執行,只執行一次。
c) doFilter() 目標請求之前攔截執行,攔截之后需要放行才開始執行目標方法。filterChain.doFilter(servletRequest,servletResponse);
d) destroy() 在容器銷毀時執行,只執行一次。
e) Filter可以攔截所有請求。包括靜態資源[css,js...]。
f) 基於函數回調實現。
g) 過濾器只能在容器初始化時被調用一次。



2. 什么是攔截器

攔截器是springmvc提供的,類似於過濾器。主要用於攔截用戶請求並作相應的處理。


2.1 攔截器常見使用場景

a) 日志記錄
b) 權限校驗
c) 登錄校驗
d) 性能檢測[檢測方法的執行時間]
其實攔截器和過濾器很像,有些使用場景。無論選用誰都能實現。需要注意的使他們彼此的使用范圍,觸發機制。

2.2 springboot整合攔截器

a) 編寫自定義攔截器類實現HandlerInterceptor接口或繼承其子類【推薦實現的方式,實現可以自動生成preHandle..】

@Component
public class InterceptorDemo implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("攔截器preHandle在控制器方法執行前執行");
        //true:表示放行
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("攔截器postHandle在控制器方法執行后執行");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("攔截器afterCompletion在請求完成后執行");
    }
}

b) 基於springmvc編寫配置類

@Configuration
// 老版本呢是繼承WebMvcConfigurerAdapter不過新版本已經放棄了,推薦用下面的方式。
public class InterceptorConfig implements WebMvcConfigurer { 

    @Autowired
    private InterceptorDemo interceptorDemo;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // ** 表示所有攔截路徑
        registry.addInterceptor(interceptorDemo).addPathPatterns("/**");
        // 或下面這種寫法  【若編寫自定義攔截器類沒有加@Component注解】
        registry.addInterceptor(new InterceptorDemo()).addPathPatterns("/**");
    }
}

2.3 攔截器詳解

a) 攔截器是依賴於SpringMVC的,需要有mvc的依賴。
b) preHandle() 在目標請求完成之前執行。有返回值Boolean類型,true:表示放行
c) postHandle() 在目標請求之完成后執行。
d) afterCompletion() 在整個請求完成之后【modelAndView已被渲染執行】。
e) 攔截器只能攔截action請求。不包括靜態資源[css,js...]。
f) 基於java反射機制實現。
g) 在攔截器的生命周期中,可以多次被調用。

關於攔截器的preHandle()方法的參數說明:
      public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){
      
      }

      @param request        current HTTP request
      @param response       current HTTP response
      @param handler        chosen handler to execute, for type and/or instance evaluation   //選擇要執行的處理程序,用於類型和/或實例計算


3. 攔截器與過濾器區別

轉自:https://www.cnblogs.com/AIPAOJIAO/p/14017338.html

1、過濾器和攔截器觸發時機不一樣,過濾器是在請求進入容器后,但請求進入servlet之前進行預處理的。請求結束返回也是,是在servlet處理完后,返回給前端之前。
2、攔截器可以獲取IOC容器中的各個bean,而過濾器就不行,因為攔截器是spring提供並管理的,spring的功能可以被攔截器使用,在攔截器里注入一個service,可以調用業務邏輯。而過濾器是JavaEE標准,只需依賴servlet api ,不需要依賴spring。
3、過濾器的實現基於回調函數。而攔截器(代理模式)的實現基於反射
4、Filter是依賴於Servlet容器,屬於Servlet規范的一部分,而攔截器則是獨立存在的,可以在任何情況下使用。
5、Filter的執行由Servlet容器回調完成,而攔截器通常通過動態代理(反射)的方式來執行。
6、Filter的生命周期由Servlet容器管理,而攔截器則可以通過IoC容器來管理,因此可以通過注入等方式來獲取其他Bean的實例,因此使用會更方便。

過濾器和攔截器非常相似,但是它們有很大的區別:

最簡單明了的區別就是==過濾器可以修改request,而攔截器不能==
過濾器需要在servlet容器中實現,攔截器可以適用於javaEE,javaSE等各種環境
攔截器可以==調用IOC容器中的各種依賴,而過濾器不能==
==過濾器只能在請求的前后使用,而攔截器可以詳細到每個方法==
==當有過濾器和攔截器時的執行流程:==





4. aop與過濾器,攔截器的區別

過濾器,攔截器攔截的是URL。AOP攔截的是類的元數據(包、類、方法名、參數等)。

過濾器並沒有定義業務用於執行邏輯前、后等,僅僅是請求到達就執行。
攔截器有三個方法,相對於過濾器更加細致,有被攔截邏輯執行前、后等。
AOP針對具體的代碼,能夠實現更加復雜的業務邏輯。

三者功能類似,但各有優勢,從過濾器--》攔截器--》切面,攔截規則越來越細致。
執行順序依次是過濾器、攔截器、切面。

4.1 三者使用場景

在編寫相對比較公用的代碼時,優先考慮過濾器,然后是攔截器,最后是aop。
比如:
權限校驗,一般情況下,所有的請求都需要做登陸校驗,此時就應該使用過濾器在最頂層做校驗;日志記錄,一般日志只會針對部分邏輯做日志記錄,而且牽扯到業務邏輯完成前后的日志記錄,因此使用過濾器不能細致地划分模塊,此時應該考慮攔截器,然而攔截器也是依據URL做規則匹配,因此相對來說不夠細致,因此我們會考慮到使用AOP實現,AOP可以針對代碼的方法級別做攔截,很適合日志功能。


免責聲明!

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



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