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

java中的過(guò)濾器 Filter應(yīng)用小結(jié)

 更新時(shí)間:2025年03月05日 14:22:29   作者:謝家小布柔  
文章主要介紹了Java Web中的過(guò)濾器(Filter)的基本概念、生命周期、配置和應(yīng)用,過(guò)濾器可以攔截請(qǐng)求和響應(yīng),用于執(zhí)行一些預(yù)處理或后處理操作,如設(shè)置編碼、校驗(yàn)用戶身份等,感興趣的朋友一起看看吧

1.過(guò)濾器 Filter

1.1.初識(shí)過(guò)濾器

1.1.1.過(guò)濾器概念

過(guò)濾器JavaWeb三大組件之一,它與Servlet很相似!過(guò)濾器是用來(lái)攔截請(qǐng)求的,而不是處理請(qǐng)求的。

當(dāng)用戶請(qǐng)求某個(gè)Servlet時(shí),會(huì)先執(zhí)行部署在這個(gè)請(qǐng)求上的Filter,如果Filter“放行”,那么會(huì)繼承執(zhí)行用戶請(qǐng)求的Servlet;如果Filter不“放行”,那么就不會(huì)執(zhí)行用戶請(qǐng)求的Servlet。

其實(shí)可以這樣理解,當(dāng)用戶請(qǐng)求某個(gè)Servlet時(shí),Tomcat會(huì)去執(zhí)行注冊(cè)在這個(gè)請(qǐng)求上的Filter,然后是否“放行”由Filter來(lái)決定??梢岳斫鉃?,F(xiàn)ilter來(lái)決定是否調(diào)用Servlet!當(dāng)執(zhí)行完成Servlet的代碼后,還會(huì)執(zhí)行Filter后面的代碼。

單個(gè)過(guò)濾器示意圖:

多個(gè)過(guò)濾器示意圖:

1前 2前 2后 1后

1.1.2.過(guò)濾器例子

創(chuàng)建一個(gè)類,實(shí)現(xiàn)javax.servlet.Filter接口,并實(shí)現(xiàn)它的三個(gè)方法:

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 {
        System.out.println("Hello Filter!!!");
    }
    @Override
    public void destroy() {
    }
}

在web.xml中進(jìn)行Filter配置:

<filter>
    <filter-name>firstFilter</filter-name>
    <filter-class>cn.tx.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>firstFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

url-pattern和Servlet的url-pattern的匹配規(guī)則一模一樣

1.完全路徑匹配 以/開(kāi)頭 例如 /aaa /aaa/bbb

2.目錄匹配 以/開(kāi)頭 例如 /aaa/* /*

3.擴(kuò)展名匹配 不能以/開(kāi)頭 例如 *.do *.action …

OK了,現(xiàn)在可以嘗試去訪問(wèn)index.jsp頁(yè)面了,看看是什么效果!

當(dāng)用戶訪問(wèn)index.jsp頁(yè)面時(shí),會(huì)執(zhí)行HelloFilter的doFilter()方法!在我們的示例中,index.jsp頁(yè)面是不會(huì)被執(zhí)行的,如果想執(zhí)行index.jsp頁(yè)面,那么我們需要放行!

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    System.out.println("filter 被執(zhí)行了!");
    filterChain.doFilter(servletRequest,servletResponse);
    System.out.println("filter 執(zhí)行完畢了!");
}

有很多同學(xué)總是錯(cuò)誤的認(rèn)為,一個(gè)請(qǐng)求在給客戶端輸出之后就算是結(jié)束了,這是不對(duì)的!其實(shí)很多事情都需要在給客戶端響應(yīng)之后才能完成!

1.2.過(guò)濾器詳解

1.2.1.過(guò)濾器生命周期

我們已經(jīng)學(xué)習(xí)過(guò)Servlet的生命周期,那么Filter的生命周期也就沒(méi)有什么難度了!

init(FilterConfig):在服務(wù)器啟動(dòng)時(shí)會(huì)創(chuàng)建Filter實(shí)例,并且每個(gè)類型的Filter只創(chuàng)建一個(gè)實(shí)例,從此不再創(chuàng)建!在創(chuàng)建完Filter實(shí)例后,會(huì)馬上調(diào)用init()方法完成初始化工作,這個(gè)方法只會(huì)被執(zhí)行一次;

doFilter(ServletRequest req,ServletResponse res,FilterChain chain):這個(gè)方法會(huì)在用戶每次訪問(wèn)“目標(biāo)資源(index.jsp)”時(shí)執(zhí)行,如果需要“放行”,那么需要調(diào)用FilterChain的doFilter(ServletRequest,ServletResponse)方法,如果不調(diào)用FilterChain的doFilter()方法,那么目標(biāo)資源將無(wú)法執(zhí)行;

destroy():服務(wù)器會(huì)在創(chuàng)建Filter對(duì)象之后,把Filter放到緩存中一直使用,通常不會(huì)銷毀它。一般會(huì)在服務(wù)器關(guān)閉時(shí)銷毀Filter對(duì)象,在銷毀Filter對(duì)象之前,服務(wù)器會(huì)調(diào)用Filter對(duì)象的destory()方法。

1.2.2.FilterConfig

你已經(jīng)看到了吧,F(xiàn)ilter接口中的init()方法的參數(shù)類型為FilterConfig類型。它的功能與ServletConfig相似,與web.xml文件中的配置信息對(duì)應(yīng)。下面是FilterConfig的功能介紹:

ServletContext getServletContext():獲取ServletContext的方法;

String getFilterName():獲取Filter的配置名稱;與元素對(duì)應(yīng);

String getInitParameter(String name):獲取Filter的初始化配置,與元素對(duì)應(yīng);

Ø Enumeration getInitParameterNames():獲取所有初始化參數(shù)的名稱。

Web.xml配置:

<filter>
    <filter-name>firstFilter</filter-name>
    <filter-class>cn.tx.filter.MyFilter</filter-class>
    <init-param>
        <param-name>encode</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>company</param-name>
        <param-value>txjava</param-value>
    </init-param>
</filter>

Filter讀取:

String filterName = filterConfig.getFilterName();
String company = filterConfig.getInitParameter("company");
Enumeration<String> names = filterConfig.getInitParameterNames();
while (names.hasMoreElements()){
    String name = names.nextElement();
    String value = filterConfig.getInitParameter(name);
}

1.2.3.FilterChain

doFilter()方法的參數(shù)中有一個(gè)類型為FilterChain的參數(shù),它只有一個(gè)方法:doFilter(ServletRequest,ServletResponse)。

前面我們說(shuō)doFilter()方法的放行,讓請(qǐng)求流訪問(wèn)目標(biāo)資源!但這么說(shuō)不嚴(yán)密,其實(shí)調(diào)用該方法的意思是,“我(當(dāng)前Filter)”放行了,但不代表其他人(其他過(guò)濾器)也放行。

也就是說(shuō),一個(gè)目標(biāo)資源上,可能部署了多個(gè)過(guò)濾器,就好比在你去北京的路上有多個(gè)打劫的匪人(過(guò)濾器),而其中第一伙匪人放行了,但不代表第二伙匪人也放行了,所以調(diào)用FilterChain類的doFilter()方法表示的是執(zhí)行下一個(gè)過(guò)濾器的doFilter()方法,或者是執(zhí)行目標(biāo)資源!

如果當(dāng)前過(guò)濾器是最后一個(gè)過(guò)濾器,那么調(diào)用chain.doFilter()方法表示執(zhí)行目標(biāo)資源,而不是最后一個(gè)過(guò)濾器,那么chain.doFilter()表示執(zhí)行下一個(gè)過(guò)濾器的doFilter()方法。

1.2.4.過(guò)濾器執(zhí)行順序

一個(gè)目標(biāo)資源可以指定多個(gè)過(guò)濾器,過(guò)濾器的執(zhí)行順序是在web.xml文件中的部署順序:

<filter>
    <filter-name>filterA</filter-name>
    <filter-class>cn.tx.filter.FilterA</filter-class>
</filter>
<filter-mapping>
    <filter-name>filterA</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
    <filter-name>filterB</filter-name>
    <filter-class>cn.tx.filter.FilterB</filter-class>
</filter>
<filter-mapping>
    <filter-name>filterB</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

FilterA:

public class FilterA 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("filter A 被執(zhí)行了!");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("filter A 執(zhí)行完畢了!");
    }
    @Override
    public void destroy() {
    }

FilterB:

public class FilterB 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("filter B 被執(zhí)行了!");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("filter B 執(zhí)行完畢了!");
    }
    @Override
    public void destroy() {
    }
}

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

filter A 被執(zhí)行了!
filter B 被執(zhí)行了!
servlet 被執(zhí)行了!!!
filter B 執(zhí)行完畢了!
filter A 執(zhí)行完畢了!

1.2.5.過(guò)濾器應(yīng)用場(chǎng)景

執(zhí)行目標(biāo)資源之前做預(yù)處理工作,例如設(shè)置編碼,這種試通常都會(huì)放行,只是在目標(biāo)資源執(zhí)行之前做一些準(zhǔn)備工作;

通過(guò)條件判斷是否放行,例如校驗(yàn)當(dāng)前用戶是否已經(jīng)登錄,或者用戶IP是否已經(jīng)被禁用;

在目標(biāo)資源執(zhí)行后,做一些后續(xù)的特殊處理工作,例如把目標(biāo)資源輸出的數(shù)據(jù)進(jìn)行處理;

1.2.6.過(guò)濾器設(shè)置目標(biāo)資源

在web.xml文件中部署Filter時(shí),可以通過(guò)“*”來(lái)執(zhí)行目標(biāo)資源:

<filter-mapping>
    <filter-name>myfilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

這一特性與Servlet完全相同!通過(guò)這一特性,我們可以在用戶訪問(wèn)敏感資源時(shí),執(zhí)行過(guò)濾器,例如:/admin/*,可以把所有管理員才能訪問(wèn)的資源放到/admin路徑下,這時(shí)可以通過(guò)過(guò)濾器來(lái)校驗(yàn)用戶身份。

還可以為指定目標(biāo)資源為某個(gè)Servlet,例如:

<servlet>
    <servlet-name>myservlet</servlet-name>
    <servlet-class>cn.tx.servlet.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>myservlet</servlet-name>
    <url-pattern>/abc</url-pattern>
</servlet-mapping>
<filter>
    <filter-name>myfilter</filter-name>
    <filter-class>cn.tx.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>myfilter</filter-name>
    <servlet-name>myservlet</servlet-name>
</filter-mapping>

當(dāng)用戶訪問(wèn)http://localhost:8080/filtertest/abc時(shí),會(huì)執(zhí)行名字為myservlet的Servlet,這時(shí)會(huì)執(zhí)行過(guò)濾器。

1.2.7.過(guò)濾器總結(jié)

Filter的三個(gè)方法:

void init(FilterConfig):在Tomcat啟動(dòng)時(shí)被調(diào)用;

void destroy():在Tomcat關(guān)閉時(shí)被調(diào)用;

void doFilter(ServletRequest,ServletResponse,FilterChain):每次有請(qǐng)求時(shí)都調(diào)用該方法;

FilterConfig類:與ServletConfig相似,用來(lái)獲取Filter的初始化參數(shù)

ServletContext getServletContext():獲取ServletContext的方法;

String getFilterName():獲取Filter的配置名稱;

String getInitParameter(String name):獲取Filter的初始化配置,與元素對(duì)應(yīng);

Enumeration getInitParameterNames():獲取所有初始化參數(shù)的名稱。

FilterChain類:

ü void doFilter(ServletRequest,ServletResponse):放行!表示執(zhí)行下一個(gè)過(guò)濾器,或者執(zhí)行目標(biāo)資源??梢栽谡{(diào)用FilterChain的doFilter()方法的前后添加語(yǔ)句,在FilterChain的doFilter()方法之前的語(yǔ)句會(huì)在目標(biāo)資源執(zhí)行之前執(zhí)行,在FilterChain的doFilter()方法之后的語(yǔ)句會(huì)在目標(biāo)資源執(zhí)行之后執(zhí)行。

1.3.過(guò)濾器應(yīng)用

過(guò)濾器解決POST中文亂碼

前臺(tái)頁(yè)面:

<form action="/filter_demo/test/post" method="post">
    姓名:<input type="text" name="name"/><br>
         <input type="submit" value="提交">
</form>

Web.xml配置

<filter>
    <filter-name>encodeFilter</filter-name>
    <filter-class>cn.tx.filter.EncodeFilter</filter-class>
    <init-param>
        <param-name>encode</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encodeFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Filter代碼:

public class EncodeFilter implements Filter{
    private String encode;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
       this.encode = filterConfig.getInitParameter("encode");
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding(encode);
        servletResponse.setContentType("text/html;charSet="+this.encode);
        servletResponse.setCharacterEncoding(this.encode);
        filterChain.doFilter(servletRequest,servletResponse);
    }
    @Override
    public void destroy() {
    }
}

Servlet代碼:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String name = request.getParameter("name");
    System.out.println(name);
    response.getWriter().write("測(cè)試中文亂碼");
}

到此這篇關(guān)于java中的過(guò)濾器 Filter應(yīng)用小結(jié)的文章就介紹到這了,更多相關(guān)java 過(guò)濾器 Filter內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • idea配置spring項(xiàng)目ApplicationContext.xml自動(dòng)生成實(shí)踐

    idea配置spring項(xiàng)目ApplicationContext.xml自動(dòng)生成實(shí)踐

    本文簡(jiǎn)述Spring配置步驟:通過(guò)文件設(shè)置添加配置項(xiàng),創(chuàng)建applicationContext.xml文件,并驗(yàn)證配置成功,為個(gè)人經(jīng)驗(yàn)總結(jié),供開(kāi)發(fā)者參考
    2025-09-09
  • Java MyBatis可視化代碼生成工具使用教程

    Java MyBatis可視化代碼生成工具使用教程

    這篇文章主要介紹了Java MyBatis可視化代碼生成工具使用教程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Java面試必備之AQS阻塞隊(duì)列和條件隊(duì)列

    Java面試必備之AQS阻塞隊(duì)列和條件隊(duì)列

    我們大概知道AQS就是一個(gè)框架,把很多功能都給實(shí)現(xiàn)了(比如入隊(duì)規(guī)則,喚醒節(jié)點(diǎn)中的線程等),我們?nèi)绻褂玫脑捴恍枰獙?shí)現(xiàn)其中的一些方法(比如tryAcquire等)就行了!這次主要說(shuō)說(shuō)AQS中阻塞隊(duì)列的的入隊(duì)規(guī)則還有條件變量,需要的朋友可以參考下
    2021-06-06
  • Spring Boot 常用注解大全

    Spring Boot 常用注解大全

    這篇文章主要介紹了Spring Boot 常用注解大全,需要的朋友可以參考下
    2024-02-02
  • Intellij IDEA基于Springboot的遠(yuǎn)程調(diào)試(圖文)

    Intellij IDEA基于Springboot的遠(yuǎn)程調(diào)試(圖文)

    這篇文章主要介紹了Intellij IDEA基于Springboot的遠(yuǎn)程調(diào)試(圖文),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • Netty通道的容器屬性Attribute詳解

    Netty通道的容器屬性Attribute詳解

    這篇文章主要介紹了Netty通道的容器屬性Attribute詳解,Netty中的Channel通道類,有類似于Map的容器功能,可以通過(guò)鍵值對(duì)的形式來(lái)保存任何Java Object的值,一般來(lái)說(shuō)可以存放一些與通道實(shí)例相關(guān)聯(lián)的屬性,比如說(shuō)服務(wù)期端的ServerSession會(huì)話實(shí)例,需要的朋友可以參考下
    2023-12-12
  • 關(guān)于Java?CPU或內(nèi)存使用率過(guò)高問(wèn)題定位

    關(guān)于Java?CPU或內(nèi)存使用率過(guò)高問(wèn)題定位

    Spring?cloud微服務(wù)廣泛應(yīng)用后,服務(wù)的監(jiān)控和運(yùn)維壓力也與日俱增,經(jīng)常有服務(wù)出現(xiàn)CPU或者內(nèi)存使用率過(guò)高的告警,那么遇到這樣的問(wèn)題我們?cè)撊绾闻挪槟??我們可以借助哪些工具?lái)定位問(wèn)題呢?本文將介紹一下遇到此類問(wèn)題的解決思路和方法
    2024-10-10
  • Spring事務(wù)失效的場(chǎng)景梳理總結(jié)

    Spring事務(wù)失效的場(chǎng)景梳理總結(jié)

    實(shí)際項(xiàng)目開(kāi)發(fā)中,如果涉及到多張表操作時(shí),為了保證業(yè)務(wù)數(shù)據(jù)的一致性,大家一般都會(huì)采用事務(wù)機(jī)制,好多小伙伴可能只是簡(jiǎn)單了解一下,遇到事務(wù)失效的情況,便會(huì)無(wú)從下手,下面這篇文章主要給大家介紹了關(guān)于Spring事務(wù)失效場(chǎng)景的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • Java字符串操作的四種正確姿勢(shì)與常用模板

    Java字符串操作的四種正確姿勢(shì)與常用模板

    在Java編程中,字符串(String)是一個(gè)非常常見(jiàn)的數(shù)據(jù)類型,用于存儲(chǔ)文本信息,無(wú)論是處理用戶輸入、讀取文件內(nèi)容還是與外部系統(tǒng)進(jìn)行通信,字符串都扮演著重要的角色,這篇文章主要介紹了Java字符串操作的四種正確姿勢(shì)與常用模板的相關(guān)資料,需要的朋友可以參考下
    2026-03-03

最新評(píng)論

宜宾市| 江北区| 高台县| 永安市| 民勤县| 安平县| 垦利县| 莲花县| 张家界市| 长岛县| 皮山县| 安泽县| 尼勒克县| 日土县| 东莞市| 衡山县| 马公市| 鄂伦春自治旗| 南昌县| 大同市| 稷山县| 丹凤县| 卓尼县| 灌南县| 冷水江市| 乐业县| 蒲城县| 抚州市| 高唐县| 林芝县| 庐江县| 江西省| 泰来县| 晋江市| 甘南县| 墨脱县| 焦作市| 兴文县| 浑源县| 诸暨市| 桃园市|