最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java Web過濾器的核心原理、實(shí)現(xiàn)與執(zhí)行順序配置方法(最新整理)

 更新時(shí)間:2025年12月04日 11:11:28   作者:ArabySide  
本文介紹了JavaWeb過濾器的核心概念、實(shí)現(xiàn)方式及執(zhí)行順序,過濾器允許在請(qǐng)求到達(dá)Servlet之前或響應(yīng)返回客戶端之前對(duì)請(qǐng)求和響應(yīng)進(jìn)行處理,感興趣的朋友跟隨小編一起看看吧

前言

過濾器是Java EE標(biāo)準(zhǔn)中Servlet規(guī)范提供的功能,也是傳統(tǒng)JavaWeb的三大組件之一(Servlet,F(xiàn)ilter和Listener)。通過過濾器可以把所有進(jìn)入Servlet容器的請(qǐng)求都攔截住,無(wú)論靜態(tài)資源還是Controller,從而實(shí)現(xiàn)一些通用的操作。

提示:以下是本篇文章正文內(nèi)容,下面案例可供參考

一、核心功能

自定義過濾器的核心能力來(lái)自Filter這個(gè)接口。這個(gè)接口分別有init(),doFilter()和destroy()方法。init和destroy的生命周期依托于Servlet容器,容器初始化的時(shí)候會(huì)執(zhí)行init()方法,容器銷毀的時(shí)候會(huì)執(zhí)行destroy()方法。

Filter 接口

package jakarta.servlet;
import java.io.IOException;
public interface Filter {
    default void init(FilterConfig filterConfig) throws ServletException {
    }
    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
    default void destroy() {
    }
}

其中最常用的是doFilter方法,在每一次請(qǐng)求管道中,都會(huì)執(zhí)行我們重寫的這個(gè)方法。doFilter有一核心的FilterChain參數(shù),它的核心作用是將請(qǐng)求傳遞給下一個(gè) Filter或最終的控制器。缺少這個(gè)調(diào)用時(shí),請(qǐng)求會(huì)卡在當(dāng)前 Filter,后續(xù)所有處理環(huán)節(jié)都不會(huì)執(zhí)行。
比如下面的doFilter方法中包含了對(duì)filterChain的調(diào)用,這樣請(qǐng)求才會(huì)傳遞到后面,否則就會(huì)中斷。

filterChain.doFilter(servletRequest, servletResponse);

另外doFilter方法中還有ServletRequest和ServletResponse這兩個(gè)參數(shù),這兩個(gè)分別對(duì)應(yīng)請(qǐng)求和響應(yīng)。我們可以通過這兩個(gè)參數(shù)來(lái)查看或設(shè)置請(qǐng)求/響應(yīng)

二、實(shí)現(xiàn)方式

過濾器本身是Servlet規(guī)范提供的功能,在Spring Boot中實(shí)現(xiàn)一個(gè)過濾器主要通過兩種方法,接下來(lái)通過兩種方式實(shí)現(xiàn)一個(gè)字符格式化過濾器和日志打印過濾器。

以下兩種寫法其中本質(zhì)上還是Spring Boot默認(rèn)使用FilterRegistrationBean來(lái)注冊(cè)自定義Filter到容器中,兩者僅僅是寫法上不同

2.1 @WebFilter + @ServletComponentScan

首先我們定義一個(gè)CharsetFilter類來(lái)實(shí)現(xiàn)Filter類,F(xiàn)ilter功能由jakarta.servlet這個(gè)包提供提供。

注意在自定義類上要使用@WebFilter()注解修飾,里面的參數(shù)則是URI路徑匹配通配符,這里設(shè)置為"/*",表示匹配所有。

CharsetFilter類主要是攔截住請(qǐng)求,該Filter接口里最為核心的方法是doFilter。我們?cè)赿oFilter的重載里寫上自定義的邏輯,比如這里是將客戶端到服務(wù)器和服務(wù)器到客戶端的數(shù)據(jù)流都設(shè)置為UTF-8的編碼格式。

值得注意的是@WebFilter需要和@ServletComponentScan搭配使用。需要在啟動(dòng)類上通過@ServletComponentScan來(lái)控制Spring Boot啟動(dòng)的時(shí)候掃描到這個(gè)被@WebFilter修飾的自定義過濾器。

通過@WebFilter + @ServletComponentScan這種實(shí)現(xiàn)本質(zhì)上是Spring引導(dǎo) Servlet 容器掃描@WebFilter最終由Servlet 容器直接調(diào)用ServletContext.addFilter()完成過濾器的注冊(cè)。

package org.araby.blognovelink.filter;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
@Slf4j
@WebFilter("/*")
public class CharsetFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("初始化統(tǒng)一字符編碼過濾器");
        Filter.super.init(filterConfig);
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("統(tǒng)一字符編碼過濾器開始執(zhí)行");
        servletRequest.setCharacterEncoding("UTF-8");
        servletResponse.setCharacterEncoding("UTF-8");
        filterChain.doFilter(servletRequest, servletResponse);
    }
    @Override
    public void destroy() {
        log.info("銷毀統(tǒng)一字符編碼過濾器");
        Filter.super.destroy();
    }
}
@SpringBootApplication
@ServletComponentScan
public class BlogNovelinkApplication {
    public static void main(String[] args) {
        SpringApplication.run(BlogNovelinkApplication.class, args);
    }
}

執(zhí)行結(jié)果里包含

2.2 @Component修飾自定義過濾器類

第二種通過在自定義過濾器類添加@Component會(huì)更加的簡(jiǎn)單,這樣就不需要在啟動(dòng)類上添加@ServletComponentScan。這種方式基于Spring的IOC容器,直接將過濾器作為Bean對(duì)象注冊(cè)到容器中,最后在請(qǐng)求管道里注入自定義過濾器。
但僅用@Component注解標(biāo)記Filter類時(shí),Spring Boot 會(huì)自動(dòng)注冊(cè)該過濾器,默認(rèn)攔截規(guī)則為所有請(qǐng)求。如果要手動(dòng)控制匹配順序,需要手動(dòng)實(shí)現(xiàn)一個(gè)配置類來(lái)實(shí)現(xiàn)FilterRegistrationBean的注冊(cè),這里后面再詳細(xì)介紹。

這里我們定義一個(gè)自定義的日志過濾器,這次只有在類上加一個(gè)@Component注解。其底層還是依賴 Spring的FilterRegistrationBean完成注冊(cè)。

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
@Slf4j
@Component
public class LogFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("初始化日志過濾器");
        Filter.super.init(filterConfig);
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("日志過濾器開始執(zhí)行");
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String uri = request.getRequestURI();
        String method = request.getMethod();
        String ip = request.getRemoteAddr();
        long startTime = System.currentTimeMillis();
        filterChain.doFilter(servletRequest, servletResponse);
        // 記錄響應(yīng)耗時(shí)
        long costTime = System.currentTimeMillis() - startTime;
        log.info("Response - URL: {}, Cost Time: {}ms", uri, costTime);
    }
    @Override
    public void destroy() {
        log.info("銷毀日志過濾器");
        Filter.super.destroy();
    }
}

三、過濾器執(zhí)行的順序

3.1 現(xiàn)象討論

假想一下有三個(gè)過濾器在請(qǐng)求管道里,分別是過濾器a,過濾器b和過濾器c。它們都是通過@WebFilter + @ServletComponentScan的方式初始化。

觀察執(zhí)行結(jié)果發(fā)現(xiàn)了一個(gè)神奇的現(xiàn)象,初始化和銷毀順序 不等于執(zhí)行順序。初始化/銷毀順序是A-C-B,而 執(zhí)行順序是A-B-C。這是因?yàn)锧WebFilter + @ServletComponentScan默認(rèn)情況下自定義過濾器其初始化順序由Servlet容器加載Servlet組件的規(guī)則決定,而執(zhí)行順序由Servlet容器構(gòu)建FilterChain時(shí)的排序規(guī)則,像Tomcat默認(rèn)會(huì)對(duì)所有@WebFilter按類名排序。

執(zhí)行結(jié)果

[INFO ] [2025-12-02 22:14:18.365] [main] [] o.araby.blognovelink.filter.AFilter - 初始化A過濾器
[INFO ] [2025-12-02 22:14:18.365] [main] [] o.araby.blognovelink.filter.CFilter - 初始化C過濾器
[INFO ] [2025-12-02 22:14:18.365] [main] [] o.araby.blognovelink.filter.BFilter - 初始化B過濾器
[INFO ] [2025-12-02 22:14:36.764] [http-nio-9090-exec-2] [] o.araby.blognovelink.filter.AFilter - A過濾器開始執(zhí)行
[INFO ] [2025-12-02 22:14:36.765] [http-nio-9090-exec-2] [] o.araby.blognovelink.filter.BFilter - B過濾器開始執(zhí)行
[INFO ] [2025-12-02 22:14:36.765] [http-nio-9090-exec-2] [] o.araby.blognovelink.filter.CFilter - C過濾器開始執(zhí)行
[INFO ] [2025-12-02 22:14:42.262] [SpringApplicationShutdownHook] [] o.araby.blognovelink.filter.AFilter - 銷毀A過濾器
[INFO ] [2025-12-02 22:14:42.262] [SpringApplicationShutdownHook] [] o.araby.blognovelink.filter.CFilter - 銷毀C過濾器
[INFO ] [2025-12-02 22:14:42.262] [SpringApplicationShutdownHook] [] o.araby.blognovelink.filter.BFilter - 銷毀B過濾器

3.2 自定義順序

既然都已經(jīng)是在Spring Boot中使用過濾器,那么我們就應(yīng)該用Spring的方式管理Filter,而不是依賴 Servlet容器的隱式行為。這里其實(shí)是采用FilterRegistrationBean來(lái)手動(dòng)定義注冊(cè)的順序,所以過濾器類可以不用@WebFilter + @ServletComponentScan或者@Component修飾。啟動(dòng)類上也不需要@ServletComponentScan。

這樣注冊(cè)過濾器的的過程由Spring Boot通過FilterRegistrationBean統(tǒng)一管理,而非直接依賴Servlet 容器的注解掃描。

這里我們定義一個(gè)配置類WebConfig ,用@Configuration注解修飾。里面手動(dòng)實(shí)現(xiàn)FilterRegistrationBean來(lái)管理定義的過濾器。

  • setFilter:添加過濾器類
  • addUrlPatterns:添加匹配路徑
  • setOrder:指定順序,數(shù)值越小,過濾器doFilter越先執(zhí)行
import org.araby.blognovelink.filter.AFilter;
import org.araby.blognovelink.filter.BFilter;
import org.araby.blognovelink.filter.CFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WebConfig {
    @Bean
    public FilterRegistrationBean<AFilter> aFilter() {
        FilterRegistrationBean<AFilter> bean = new FilterRegistrationBean<>();
        bean.setFilter(new AFilter());
        bean.addUrlPatterns("/*");
        bean.setOrder(1); // 最先執(zhí)行
        return bean;
    }
    @Bean
    public FilterRegistrationBean<BFilter> bFilter() {
        FilterRegistrationBean<BFilter> bean = new FilterRegistrationBean<>();
        bean.setFilter(new BFilter());
        bean.addUrlPatterns("/*");
        bean.setOrder(2);
        return bean;
    }
    @Bean
    public FilterRegistrationBean<CFilter> cFilter() {
        FilterRegistrationBean<CFilter> bean = new FilterRegistrationBean<>();
        bean.setFilter(new CFilter());
        bean.addUrlPatterns("/*");
        bean.setOrder(3); // 最后執(zhí)行
        return bean;
    }
}

到此這篇關(guān)于Java Web過濾器的核心原理、實(shí)現(xiàn)與執(zhí)行順序配置的文章就介紹到這了,更多相關(guān)javaweb過濾器原理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot整合liteflow的實(shí)現(xiàn)示例

    springboot整合liteflow的實(shí)現(xiàn)示例

    本文主要介紹了在Spring Boot項(xiàng)目中整合Liteflow規(guī)則引擎,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-12-12
  • MyBatis trim標(biāo)簽核心用法代碼實(shí)戰(zhàn)

    MyBatis trim標(biāo)簽核心用法代碼實(shí)戰(zhàn)

    MyBatis的<trim>標(biāo)簽用于動(dòng)態(tài)SQL拼接,處理SQL前后綴和多余關(guān)鍵字,避免語(yǔ)法錯(cuò)誤,提升代碼可維護(hù)性,本文給大家介紹MyBatis trim標(biāo)簽核心用法代碼實(shí)戰(zhàn),感興趣的朋友跟隨小編一起看看吧
    2026-03-03
  • idea生成類注釋和方法注釋的正確方法(推薦)

    idea生成類注釋和方法注釋的正確方法(推薦)

    這篇文章主要介紹了idea生成類注釋和方法注釋的正確方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • IDEA中Jar包的制作和使用方法

    IDEA中Jar包的制作和使用方法

    這篇文章主要介紹了IDEA的Jar包的制作和使用方法,文中補(bǔ)充介紹了idea的pom依賴配置后,不會(huì)自動(dòng)下載jar包的解決辦法,感興趣的朋友跟隨小編一起看看吧
    2025-04-04
  • maven使用systemPath方式加載本地jar的實(shí)現(xiàn)

    maven使用systemPath方式加載本地jar的實(shí)現(xiàn)

    本文介紹Maven通過systemPath加載本地第三方JAR的方法,需配置依賴和插件以確保打包和運(yùn)行,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-06-06
  • Spring?中?PageHelper?不生效問題及解決方法

    Spring?中?PageHelper?不生效問題及解決方法

    這篇文章主要介紹了Spring?中?PageHelper?不生效問題,使用這個(gè)插件時(shí)要注意版本的問題,不同的版本可能 PageHelper 不會(huì)生效,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • Java實(shí)現(xiàn)動(dòng)態(tài)生成GIF圖像詳解

    Java實(shí)現(xiàn)動(dòng)態(tài)生成GIF圖像詳解

    在互聯(lián)網(wǎng)上有許多有趣的場(chǎng)景,其中的一種就是動(dòng)圖。這不是視頻,而是一種GIF圖像信息。本文將利用Java實(shí)現(xiàn)動(dòng)態(tài)生成GIF圖像功能,需要的可以參考一下
    2022-09-09
  • WeakHashMap的使用方法詳解

    WeakHashMap的使用方法詳解

    這篇文章主要介紹了WeakHashMap的使用方法詳解的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-10-10
  • SpringMVC使用@ExceptionHandler注解在Controller中處理異常

    SpringMVC使用@ExceptionHandler注解在Controller中處理異常

    這篇文章主要為大家介紹了SpringMVC使用@ExceptionHandler注解在Controller中處理異常示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • Java for循環(huán)的妙用之雞兔同籠問題

    Java for循環(huán)的妙用之雞兔同籠問題

    這篇文章主要給大家介紹了關(guān)于Java for循環(huán)的妙用之雞兔同籠問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04

最新評(píng)論

腾冲县| 赤城县| 甘南县| 平武县| 师宗县| 昭苏县| 蒲城县| 建昌县| 苗栗县| 宁国市| 墨江| 金乡县| 丹江口市| 柘荣县| 碌曲县| 运城市| 福鼎市| 怀仁县| 广宗县| 乐清市| 湖南省| 德兴市| 玉山县| 兴国县| 北安市| 穆棱市| 行唐县| 绍兴县| 太仆寺旗| 准格尔旗| 疏勒县| 渑池县| 都昌县| 东乡县| 凤翔县| 宝应县| 常熟市| 许昌市| 金华市| 渝北区| 利辛县|