JavaWeb三大組件之Filter

JavaWeb有三大組件秘症,Servlet照卦、Listener、Filter乡摹。本文將介紹Filter役耕,主要從用處、種類聪廉、使用方法等進(jìn)行介紹瞬痘。

一、用處

Filter可以認(rèn)為是Servlet的一種“加強(qiáng)版”板熊。使用Filter完整的流程是:Filter對用戶請求進(jìn)行預(yù)處理图云,接著將請求交給Servlet進(jìn)行處理并生成響應(yīng),最后Filter再對服務(wù)器響應(yīng)進(jìn)行后處理邻邮。

Filter有以下幾個用處:

  • 在HttpServletRequest到達(dá)Servlet之前竣况,攔截客戶的HttpServletRequest;
  • 根據(jù)需要檢查HttpServletRequest筒严,也可以修改HttpServletRequest頭和數(shù)據(jù)丹泉;
  • 在HttpServletResponse到達(dá)客戶端之前,攔截HttpServletResponse鸭蛙;
  • 根據(jù)需要檢查HttpServletResponse摹恨,也可以修改HttpServletResponse頭和數(shù)據(jù)。

二娶视、種類

  • 用戶授權(quán)的Filter:Filter負(fù)責(zé)檢查用戶請求晒哄,根據(jù)請求過濾用戶非法請求(比如對用戶登錄狀態(tài)進(jìn)行判定);
  • 日志Filter:詳細(xì)記錄某些特殊的用戶請求肪获;
  • 負(fù)責(zé)解碼的Filter:包括對非標(biāo)準(zhǔn)編碼的請求解碼寝凌;
  • 能改變XML內(nèi)容的XSLT Filter等;
  • Filter可負(fù)責(zé)攔截多個請求或響應(yīng)孝赫;一個請求或響應(yīng)也可被多個Filter攔截较木。

三、使用方法

3.1 創(chuàng)建Filter步驟

1)創(chuàng)建Filter處理類青柄;
2)web.xml文件中配置Filter伐债,或通過注解的方式配置预侯。(順便說一下,三大組件都需要在web.xml中進(jìn)行配置)

3.2 創(chuàng)建Filter類

創(chuàng)建Filter類必須實(shí)現(xiàn)Filter接口峰锁,F(xiàn)ilter接口中包含三個方法:

  • void init(FilterConfig config):用于完成Filter的初始化萎馅;
  • void destroy():用于Filter銷毀前,完成某些資源的回收虹蒋;
  • void doFilter(ServletRequest srq, ServletResponse srp, FilterChain chain):實(shí)現(xiàn)過濾功能校坑,該方法就是對每個請求及響應(yīng)增加的額外處理。

doFilter()方法千诬,在該方法中可實(shí)現(xiàn)對用戶請求進(jìn)行預(yù)處理耍目,也可實(shí)現(xiàn)對服務(wù)器響應(yīng)進(jìn)行后處理,分界線就是是否調(diào)用了chain.doFiler()徐绑,調(diào)用之前是請求預(yù)處理邪驮,調(diào)用之后是響應(yīng)后處理。這是因為傲茄,web服務(wù)器會檢查FilterChain對象中是否還有Filter毅访,如果有,則調(diào)用下一個Filter盘榨,沒有喻粹,則調(diào)用目標(biāo)資源。

3.3 配置Filter

與配置Servlet相似草巡,配置Filter守呜,需要配置兩個部分:
1)配置Filter名;
2)配置Filter攔截URL模式
與Servlet的區(qū)別在于:Servlet通常只配置一個URL山憨,而Filter可以同時攔截多個請求的URL查乒。因此,在配置Filter的URL模式時通常會使用模式字符串郁竟,使得Filter可以攔截多個請求玛迄。配置的方式有兩種:在Filter類中通過注解進(jìn)行配置,在web.xml文件中進(jìn)行配置棚亩。

3.3.1 注解配置

使用@WebFilter注解進(jìn)行配置蓖议,并添加屬性。常用屬性如下:

屬性 是否必需 說明
asynSupported 指定該Filter是否支持異步操作模式讥蟆。
dispatcherTypes 指定該Filter僅對那種dispatcher模式的請求進(jìn)行過濾勒虾。該屬性支持ASTNC、ERROR攻询、FORWARD从撼、INCLUDE州弟、REQUEST這五個值的任意組合钧栖。默認(rèn)值是同時過濾5種模式的請求低零。
displayName 指定該Filter的顯示名
filterName 指定該Filter的名稱
initParams 用于為該Filter配置參數(shù)
servletNames 該屬性值可指定多個Servlet的名稱,用于指定該Filter僅對這幾個Servlet執(zhí)行過濾拯杠。
urlPatterns/value 這兩個屬性的作用完全相同掏婶。都指定該Filter所攔截的URL。

3.3.2 web.xml中進(jìn)行配置

<!-- 定義Filter -->
    <filter>
        <filter-name>log</filter-name>
        <filter-class>filter.LogFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>log</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

Filter里doFilter()方法里的代碼就是從多個Servlet的service()方法里抽出的通用代碼潭陪。通過使用Filter可以實(shí)現(xiàn)更好的代碼復(fù)用雄妥。


Filter作用圖.png

Filter和Servlet具有完全相同的生命周期行為,且Filter也可以通過<init-param.../>元素或@WebFilter的initParams屬性來配置初始化參數(shù)依溯,獲取Filter的初始化參數(shù)則使用FilterConfig的getInitParameter()方法老厌。

四、舉個栗子

/**
 * AuthorityFilter.java
 */

@WebFilter(filterName = "authority", urlPatterns = {"/*"}, initParams = {
        @WebInitParam(name = "encoding",value = "UTF-8"),
        @WebInitParam(name = "loginPage",value = "/login.jsp"),
        @WebInitParam(name = "proLogin",value = "proLogin.jsp")
})
public class AuthorityFilter implements Filter{

    private FilterConfig config;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.config = filterConfig;
    }

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

        /**
         * 通過config獲取初始化參數(shù)
         */
        String encoding = this.config.getInitParameter("encoding");
        String loginPage = this.config.getInitParameter("loginPage");
        String proLogin = this.config.getInitParameter("proLogin");
        /**
         * 通過獲取到的初始化參數(shù)設(shè)置解碼格式
         */
        servletRequest.setCharacterEncoding(encoding);
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpSession session = httpServletRequest.getSession(true);
        String requestPath = httpServletRequest.getServletPath();
        /**
         * 若用戶未登錄黎炉,并且請求地址不是登錄頁和處理登錄頁枝秤,跳轉(zhuǎn)到登錄頁;
         * 若登錄了慷嗜,則調(diào)用filterChain.doFilter()返回資源淀弹。
         */
        if (session.getAttribute("user")==null
                && !requestPath.endsWith(loginPage)
                && !requestPath.endsWith(proLogin))
        {
            httpServletRequest.setAttribute("tip","您還沒有登錄");
            httpServletRequest.getRequestDispatcher(loginPage).forward(httpServletRequest,servletResponse);
        } else {
            filterChain.doFilter(httpServletRequest,servletResponse);
        }
    }

    @Override
    public void destroy() {
        this.config = null;
    }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市庆械,隨后出現(xiàn)的幾起案子薇溃,更是在濱河造成了極大的恐慌,老刑警劉巖缭乘,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沐序,死亡現(xiàn)場離奇詭異,居然都是意外死亡堕绩,警方通過查閱死者的電腦和手機(jī)薄啥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來逛尚,“玉大人垄惧,你說我怎么就攤上這事〈履” “怎么了到逊?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長滤钱。 經(jīng)常有香客問我觉壶,道長,這世上最難降的妖魔是什么件缸? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任铜靶,我火速辦了婚禮喷户,結(jié)果婚禮上雷蹂,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好沙庐,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布振惰。 她就那樣靜靜地躺著松申,像睡著了一般检眯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上涩笤,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天嚼吞,我揣著相機(jī)與錄音,去河邊找鬼蹬碧。 笑死舱禽,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的恩沽。 我是一名探鬼主播呢蔫,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼飒筑!你這毒婦竟也來了片吊?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤协屡,失蹤者是張志新(化名)和其女友劉穎俏脊,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肤晓,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡爷贫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了补憾。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漫萄。...
    茶點(diǎn)故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖盈匾,靈堂內(nèi)的尸體忽然破棺而出腾务,到底是詐尸還是另有隱情,我是刑警寧澤削饵,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布岩瘦,位于F島的核電站,受9級特大地震影響窿撬,放射性物質(zhì)發(fā)生泄漏启昧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一劈伴、第九天 我趴在偏房一處隱蔽的房頂上張望密末。 院中可真熱鬧,春花似錦、人聲如沸严里。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽田炭。三九已至师抄,卻和暖如春漓柑,著一層夾襖步出監(jiān)牢的瞬間教硫,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工辆布, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瞬矩,地道東北人。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓锋玲,卻偏偏與公主長得像景用,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子惭蹂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 本文包括:1伞插、Filter簡介2、Filter是如何實(shí)現(xiàn)攔截的盾碗?3媚污、Filter開發(fā)入門4、Filter的生命周期...
    廖少少閱讀 7,282評論 3 56
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架廷雅,建立于...
    Hsinwong閱讀 22,435評論 1 92
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理耗美,服務(wù)發(fā)現(xiàn),斷路器航缀,智...
    卡卡羅2017閱讀 134,704評論 18 139
  • IOC 控制反轉(zhuǎn)容器控制程序?qū)ο笾g的關(guān)系商架,而不是傳統(tǒng)實(shí)現(xiàn)中,有程序代碼之間控制芥玉,又名依賴注入蛇摸。All 類的創(chuàng)建,...
    irckwk1閱讀 948評論 0 0
  • 很多人,尤其是步入中年的女士,平常很少鍛煉身體,手臂上堆積了厚厚的脂肪,手臂一動,脂肪就變成天然的“蝴蝶袖”灿巧。 為...
    一顆梧桐樹閱讀 3,463評論 0 9