spring boot 過濾器、攔截器的區別與使用


 

攔截器與過濾器的區別:

——————————————看臉的時代

      

 

 

  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的實例,因此使用會更方便。

 

 

spring boot 使用過濾器

兩種方式: 
1、使用spring boot提供的FilterRegistrationBean注冊Filter 
2、使用原生servlet注解定義Filter 
兩種方式的本質都是一樣的,都是去FilterRegistrationBean注冊自定義Filter

  方式一: (使用spring boot提供的FilterRegistrationBean注冊Filter 
①、先定義Filter:

package com.hwm.filter;

import javax.servlet.*;
import java.io.IOException;

public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // do something 處理request 或response
        System.out.println("filter1");
        // 調用filter鏈中的下一個filter
        filterChain.doFilter(servletRequest,servletResponse);
    }
    @Override
    public void destroy() {

    }
}

②、注冊自定義Filter

@Configuration
public class FilterConfig { @Bean public FilterRegistrationBean registrationBean() {  FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new MyFilter()); filterRegistrationBean.addUrlPatterns("/*"); return filterRegistrationBean; } }

 

方式一的①②步驟可以用下面這段代碼代替:

@Configuration
public class FilterConfig {
 
    @Bean
    public FilterRegistrationBean registFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setFilter(new LogCostFilter());
        registration.addUrlPatterns("/*");
        registration.setName("LogCostFilter");
        registration.setOrder(1);
        return registration;
    }
 
}
public class LogCostFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
 
    }
 
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        long start = System.currentTimeMillis();
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("Execute cost="+(System.currentTimeMillis()-start));
    }
 
    @Override
    public void destroy() {
 
    }
}

 

 方式二:(使用原生servlet注解定義Filter )

// 注入spring容器
@Component
// 定義filterName 和過濾的url
@WebFilter(filterName = "my2Filter" ,urlPatterns = "/*")
public class My2Filter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("filter2");
    }
    @Override
    public void destroy() {

    }
}

 這里直接用@WebFilter就可以進行配置,同樣,可以設置url匹配模式,過濾器名稱等。這里需要注意一點的是@WebFilter這個注解是Servlet3.0的規范,並不是Spring boot提供的。除了這個注解以外,我們還需在啟動類中加另外一個注解:@ServletComponetScan,指定掃描的包。

 

攔截器的配置

  首先我們實現攔截器類:

 

public class LogCostInterceptor implements HandlerInterceptor {
    long start = System.currentTimeMillis();
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        start = System.currentTimeMillis();
        return true;
    }
 
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("Interceptor cost="+(System.currentTimeMillis()-start));
    }
 
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }
}

  我們還需要實現HandlerInterceptor這個接口,這個接口包括三個方法,preHandle是請求執行前執行的,postHandler是請求結束執行的,但只有preHandle方法返回true的時候才會執行,afterCompletion是視圖渲染完成后才執行,同樣需要preHandle返回true,                  該方法通常用於清理資源等工作。除了實現上面的接口外,我們還需對其進行配置:

@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {
 
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LogCostInterceptor()).addPathPatterns("/**");
        super.addInterceptors(registry);
    }
}

  這里我們繼承了WebMVCConfigurerAdapter,這里我們重寫了addInterceptors這個方法,進行攔截器的配置,主要配置項就兩個,一個是指定攔截器,第二個是指定攔截的URL。現在我們再啟動系統訪問任意一個URL:

 

 

 

待續.........

 


免責聲明!

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



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