springboot2.x | 過濾器(Filter)的使用

servlet簡介

過濾器,依靠servlet技術(shù)。
Java Servlet 是運(yùn)行在 Web 服務(wù)器或應(yīng)用服務(wù)器上的程序,它是作為來自 Web 瀏覽器或其他 HTTP 客戶端的請求和 HTTP 服務(wù)器上的數(shù)據(jù)庫或應(yīng)用程序之間的中間層。
servlet文檔:
https://www.runoob.com/servlet/servlet-intro.html

servlet 和tomcat 是什么關(guān)系?

過濾器簡介

過濾器Filter,是Servlet的的一個(gè)實(shí)用技術(shù)了??赏ㄟ^過濾器,對請求進(jìn)行攔截,比如讀取session判斷用戶是否登錄、判斷訪問的請求URL是否有訪問權(quán)限(黑白名單)等。主要還是可對請求進(jìn)行預(yù)處理。

1.過濾器和攔截器觸發(fā)時(shí)機(jī)不一樣,過濾器是在請求進(jìn)入容器后,但請求進(jìn)入servlet之前進(jìn)行預(yù)處理的。請求結(jié)束返回也是,是在servlet處理完后,返回給前端之前。


flq.png

2.攔截器可以獲取IOC容器中的各個(gè)bean,而過濾器就不行,因?yàn)閿r截器是spring提供并管理的,spring的功能可以被攔截器使用,在攔截器里注入一個(gè)service,可以調(diào)用業(yè)務(wù)邏輯。而過濾器是JavaEE標(biāo)準(zhǔn),只需依賴servlet api ,不需要依賴spring。


gg.png

1 通過@WebFilter來定義filter,

自定義 AllUrlFilter

@Slf4j
@WebFilter(filterName = "allurlfilter", urlPatterns = {"/*"})
public class AllUrlFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        log.info("all url filter -->" + filterConfig.toString());
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("all url filter do filter");

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        System.out.println(request.getHeader("token"));
        //往下文傳遞
        filterChain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        log.info("all url filter do destroy");
    }
}

在springboot 啟動器類上加上注解 @ServletComponentScan

@SpringBootApplication
@ServletComponentScan
public class StudySpringbootApplication {
    public static void main(String[] args) {
        SpringApplication.run(StudySpringbootApplication.class, args);
    }
}

總結(jié):
Filter使用白名單過濾Url的方式,配置需要攔截的Url,如果想設(shè)置不過濾某些Url需要在doFilter方法中指定。
通過@WebFilter的方式定義Filter,默認(rèn)使用Filter的類名設(shè)置優(yōu)先級。使用FilterRegistrationBean可以指定優(yōu)先級

2 filter 中的異常處理

2.1 制造錯(cuò)誤

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        log.info("all url filter do filter");

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        System.out.println(request.getHeader("token"));

        try {
            int i = 0 / 0;
        } catch (Exception e) {
            //錯(cuò)誤封裝在 request 中
            request.setAttribute("errormsg", e.getMessage());
            //
            request.getRequestDispatcher("/500").forward(request, response);
        }

        filterChain.doFilter(request, response);
    }

盡量使用request.getRequestDispatcher("/500").forward(req, resp);此方式只會在服務(wù)器內(nèi)部轉(zhuǎn)發(fā)客戶端地址不會發(fā)生任何改變;如果使用response.sendRedirect("/500");請求轉(zhuǎn)發(fā),客戶端地址會發(fā)生改變

2.2 添加/500 url

  @GetMapping("/500")
    public Response excep401(HttpServletRequest request) throws CustomException {

        System.out.println(request.getAttribute("errormsg"));

        throw new CustomException();
    }

方法2 : 通過FilterRegistrationBean來定義 多個(gè)filter

所有的filter 去掉 @WebFilter

3.1 新建HelloFilter

@Slf4j
//@WebFilter(filterName = "helloFilter" , urlPatterns = {"/hello/*"})
public class HelloFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        log.info("hello filter --> " + filterConfig.toString());
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        log.info("hello do filter");

        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

        log.info("hello do destroy");
    }
}

3.2 新建UserFilter

@Slf4j
//@WebFilter(filterName = "userFilter", urlPatterns = {"/user/*"})
public class UserFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        log.info("user filter --> " + filterConfig.toString());
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        log.info("user do filter");

        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

        log.info("user do destroy");

    }
}

3.3 新建 FilterConfig 配置

@Configuration
public class FilterConfig {

    @Bean
    public AllUrlFilter allUrlFilter(){
        return new AllUrlFilter();
    }

    @Bean
    public UserFilter userFilter(){
        return new UserFilter();
    }

    @Bean
    public HelloFilter helloFilter(){
        return new HelloFilter();
    }

    @Bean
    public FilterRegistrationBean filterRegistrationBean(AllUrlFilter allUrlFilter){
        FilterRegistrationBean registration = new FilterRegistrationBean();

        registration.setFilter(allUrlFilter);
        registration.setName("allUrlFilter");
        List<String> urlList  =  new ArrayList<>();
        urlList.add("/*");
        registration.setUrlPatterns(urlList);
        registration.setOrder(1);

        return registration;
    }


    @Bean
    public FilterRegistrationBean filterRegistrationBea2(HelloFilter helloFilter){
        FilterRegistrationBean registration = new FilterRegistrationBean();

        registration.setFilter(helloFilter);
        registration.setName("helloFilter");
        List<String> urlList  =  new ArrayList<>();
        urlList.add("/hello/*");
        registration.setUrlPatterns(urlList);
        registration.setOrder(2);

        return registration;
    }


    @Bean
    public FilterRegistrationBean filterRegistrationBea3(UserFilter userFilter){
        FilterRegistrationBean registration = new FilterRegistrationBean();

        registration.setFilter(userFilter);
        registration.setName("userFilter");
        List<String> urlList  =  new ArrayList<>();
        urlList.add("/user/*");
        registration.setUrlPatterns(urlList);
        registration.setOrder(3);

        return registration;
    }

}

SpringBoot中使用Filter和Interceptor
https://juejin.cn/post/6844903869927931918
Spring Interceptor vs Filter
https://juejin.cn/post/6844903828970553358
SpringBoot圖文教程6—SpringBoot中過濾器的使用
https://juejin.cn/post/6844904072173060109

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容