欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

1.過濾器 Filter

1.1.初識過濾器

1.1.1.過濾器概念

過濾器JavaWeb三大組件之一,它與Servlet很相似!過濾器是用來攔截請求的,而不是處理請求的。

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

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

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

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

1前 2前 2后 1后

1.1.2.過濾器例子

創(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.完全路徑匹配 以/開頭 例如 /aaa /aaa/bbb

2.目錄匹配 以/開頭 例如 /aaa/* /*

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

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

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

@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è)請求在給客戶端輸出之后就算是結(jié)束了,這是不對的!其實(shí)很多事情都需要在給客戶端響應(yīng)之后才能完成!

1.2.過濾器詳解

1.2.1.過濾器生命周期

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

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

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

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

1.2.2.FilterConfig

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

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

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

String getInitParameter(String name):獲取Filter的初始化配置,與元素對應(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)。

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

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

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

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

一個(gè)目標(biāo)資源可以指定多個(gè)過濾器,過濾器的執(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.過濾器應(yīng)用場景

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

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

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

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

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

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

這一特性與Servlet完全相同!通過這一特性,我們可以在用戶訪問敏感資源時(shí),執(zhí)行過濾器,例如:/admin/*,可以把所有管理員才能訪問的資源放到/admin路徑下,這時(shí)可以通過過濾器來校驗(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)用戶訪問http://localhost:8080/filtertest/abc時(shí),會執(zhí)行名字為myservlet的Servlet,這時(shí)會執(zhí)行過濾器。

1.2.7.過濾器總結(jié)

Filter的三個(gè)方法:

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

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

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

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

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

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

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

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

FilterChain類:

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

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

過濾器解決POST中文亂碼

前臺頁面:

<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("測試中文亂碼");
}

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

相關(guān)文章

  • SpringMVC Controller解析ajax參數(shù)過程詳解

    SpringMVC Controller解析ajax參數(shù)過程詳解

    這篇文章主要介紹了SpringMVC Controller解析ajax參數(shù)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • 攔截Druid數(shù)據(jù)源自動注入帳密解密實(shí)現(xiàn)詳解

    攔截Druid數(shù)據(jù)源自動注入帳密解密實(shí)現(xiàn)詳解

    這篇文章主要為大家介紹了攔截Druid數(shù)據(jù)源自動注入帳密解密實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • java圖片格式轉(zhuǎn)換的三段代碼

    java圖片格式轉(zhuǎn)換的三段代碼

    這篇文章主要分享了java圖片格式轉(zhuǎn)換的三段代碼,小編查找資料整理了java圖片格式轉(zhuǎn)換的三段不同代碼,推薦給大家。
    2015-11-11
  • springboot泛型封裝開發(fā)方式

    springboot泛型封裝開發(fā)方式

    這篇文章主要介紹了springboot泛型封裝開發(fā)方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Maven中exec插件執(zhí)行Java程序的實(shí)現(xiàn)

    Maven中exec插件執(zhí)行Java程序的實(shí)現(xiàn)

    在Maven項(xiàng)目中,可以使用Maven的插件來執(zhí)行Java程序,本文主要介紹了Maven中exec插件執(zhí)行Java程序的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • java如何遠(yuǎn)程加載class文件

    java如何遠(yuǎn)程加載class文件

    這篇文章主要介紹了java如何遠(yuǎn)程加載class文件問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • java字符串常用操作方法(查找、截取、分割)

    java字符串常用操作方法(查找、截取、分割)

    今天小編就為大家分享一篇java字符串常用操作方法(查找、截取、分割),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • Java數(shù)據(jù)結(jié)構(gòu)之有向圖設(shè)計(jì)與實(shí)現(xiàn)詳解

    Java數(shù)據(jù)結(jié)構(gòu)之有向圖設(shè)計(jì)與實(shí)現(xiàn)詳解

    有向圖是具有方向性的圖,由一組頂點(diǎn)和一組有方向的邊組成,每條方向的邊都連著一對有序的頂點(diǎn)。本文為大家介紹的是有向圖的設(shè)計(jì)與實(shí)現(xiàn),需要的可以參考一下
    2022-11-11
  • Java隨機(jī)值設(shè)置(java.util.Random類或Math.random方法)

    Java隨機(jī)值設(shè)置(java.util.Random類或Math.random方法)

    在編程中有時(shí)我們需要生成一些隨機(jī)的字符串作為授權(quán)碼、驗(yàn)證碼等,以確保數(shù)據(jù)的安全性和唯一性,這篇文章主要給大家介紹了關(guān)于Java隨機(jī)值設(shè)置的相關(guān)資料,主要用的是java.util.Random類或Math.random()方法,需要的朋友可以參考下
    2024-08-08
  • MyBatis傳入?yún)?shù)為List對象的實(shí)現(xiàn)

    MyBatis傳入?yún)?shù)為List對象的實(shí)現(xiàn)

    這篇文章主要介紹了MyBatis傳入?yún)?shù)為List對象的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03

最新評論