對(duì) WEB 過(guò)濾器的思考
Posted on 2009-08-26 23:28 Gavin.lee 閱讀(392) 評(píng)論(0) 編輯 收藏 所屬分類(lèi): web 積累(前端 + 后臺(tái))過(guò)濾器基本概念:
過(guò)濾器能夠?qū)δ繕?biāo)資源的請(qǐng)求和響應(yīng)進(jìn)行截取,在過(guò)濾器中對(duì)用戶請(qǐng)求進(jìn)行統(tǒng)一處理。
過(guò)濾器是一個(gè)程序,它先于與之相關(guān)的servlet或JSP頁(yè)面運(yùn)行在服務(wù)器上。過(guò)濾器可附加到一個(gè)或多個(gè)servlet或JSP頁(yè)面上,并且可以檢查
進(jìn)入這些資源的請(qǐng)求信息。過(guò)濾器是雙向的,容器接受到一個(gè)對(duì)資源的請(qǐng)求時(shí),它將判斷是否有過(guò)濾器與這個(gè)資源相關(guān)聯(lián)。如果有,那么容器將
把請(qǐng)求交給過(guò)濾器進(jìn)行處理。在過(guò)濾器中,你可以改變請(qǐng)求的內(nèi)容,或者重新設(shè)置請(qǐng)求的報(bào)頭信息,然后再將請(qǐng)求發(fā)送給目標(biāo)資源。當(dāng)目標(biāo)資源
對(duì)請(qǐng)求作出響應(yīng)時(shí)候,容器同樣會(huì)將響應(yīng)先轉(zhuǎn)發(fā)給過(guò)濾器,再過(guò)濾器中,你可以對(duì)響應(yīng)的內(nèi)容進(jìn)行轉(zhuǎn)換,然后再將響應(yīng)發(fā)送到客戶端
過(guò)濾器的構(gòu)造的全面解析:
任何一個(gè)過(guò)濾器,都要實(shí)現(xiàn)Filter接口,重寫(xiě)init,doFilter,destory方法。
①

init會(huì)在容器初始化時(shí)被調(diào)用
init方法只會(huì)在該Filter第一次被調(diào)用時(shí)初始化。對(duì)于簡(jiǎn)單的過(guò)濾器,可提供此方法的一個(gè)空體,但有兩個(gè)原因需要使用init。首先,F(xiàn)ilterConfig對(duì)象提
供對(duì)servlet環(huán)境及web.xml文件中指派的過(guò)濾器名的訪問(wèn)。因此,普遍的辦法是利用init將FilterConfig對(duì)象存放在一個(gè)字段中,以便doFilter方法能夠訪
問(wèn)servlet環(huán)境或過(guò)濾器名。其次,F(xiàn)ilterConfig對(duì)象具有一個(gè)getInitParameter方法,它能夠訪問(wèn)部署描述符文件(web.xml)中分配的過(guò)濾器初始化參
數(shù)。
FilterConfig接口:
javax.servlet.FilterConfig接口類(lèi)似于javax.servlet.ServletConfig接口,用于在過(guò)濾器初始化時(shí),向其傳遞信息。ilterConfig
接口有容器實(shí)現(xiàn),容器將其作為參數(shù)傳入過(guò)濾器對(duì)象的init()方法中。在FilterConfig接口,定義了4個(gè)方法:
·public java.lang.String getFilterName()
得到描述符中指定的過(guò)濾器的名字。
·public java.lang.String getInitParameter(java.lang.String name)
返回在部署描述中指定的名字為name的初始化參數(shù)的值。如果不存在返回null.
·public java.util.Enumeration getInitParameterNames()
返回過(guò)濾器的所有初始化參數(shù)的名字的枚舉集合。
·public ServletContext getServletContext()
返回Servlet上下文對(duì)象的引用。
②

1.ServletRequest對(duì)象,此對(duì)象給過(guò)濾器提供了對(duì)進(jìn)入的信息(包括表單數(shù)據(jù)、cookie和HTTP請(qǐng)求頭)的完全訪問(wèn),多數(shù)情況下,需要將
ServletRequest對(duì)象構(gòu)造成HttpServletRequest對(duì)象。
2.ServletResponse對(duì)象,簡(jiǎn)單過(guò)濾器則忽略該對(duì)象。
3.FilterChain對(duì)象,在調(diào)用此對(duì)象的doFilter方法時(shí),激活下一個(gè)相關(guān)的過(guò)濾器。如果沒(méi)有另一個(gè)過(guò)濾器與servlet或JSP頁(yè)面關(guān)聯(lián),則servlet或JSP頁(yè)面被
激活。
對(duì)于doFilter方法,是每次請(qǐng)求與此過(guò)濾器相關(guān)的servlet或JSP頁(yè)面都會(huì)調(diào)用的方法。除了在兩個(gè)情形下要使用它以外,通常忽略這個(gè)參數(shù)。首先,如
果希望完全阻塞對(duì)相關(guān)servlet或JSP頁(yè)面的訪問(wèn)。可調(diào)用response.getWriter并直接發(fā)送一個(gè)響應(yīng)到客戶機(jī)。其次,如果希望修改相關(guān)的servlet或JSP頁(yè)
面的輸出,可把響應(yīng)包含在一個(gè)收集所有發(fā)送到它的輸出的對(duì)象中。然后,在調(diào)用serlvet或JSP頁(yè)面后,過(guò)濾器可檢查輸出,如果合適就修改它,
之后發(fā)送到客戶機(jī)。
③

此方法在利用一個(gè)給定的過(guò)濾器對(duì)象永久地終止服務(wù)器(如關(guān)閉服務(wù)器)時(shí)調(diào)用。大多數(shù)過(guò)濾器簡(jiǎn)單地為此方法提供一個(gè)空體,不過(guò),可利用它
來(lái)完成諸如關(guān)閉過(guò)濾器使用的文件或數(shù)據(jù)庫(kù)連接池等清除任務(wù)。
說(shuō)說(shuō)FilterChain對(duì)象的doFilter方法,F(xiàn)ilter接口的doFilter方法以一個(gè)FilterChain對(duì)象作為它的第三個(gè)參數(shù)。在調(diào)用該對(duì)象的doFilter方法時(shí),激活下一個(gè)
相關(guān)的過(guò)濾器。這個(gè)過(guò)程一般持續(xù)到鏈中最后一個(gè)過(guò)濾器為止。在最后一個(gè)過(guò)濾器調(diào)用其FilterChain對(duì)象的doFilter方法時(shí),激活servlet或頁(yè)面自身。
但是,鏈中的任意過(guò)濾器都可以通過(guò)不調(diào)用其FilterChain的doFilter方法中斷這個(gè)過(guò)程。在這樣的情況下,不再調(diào)用JSP頁(yè)面的serlvet,并且中斷此調(diào)
用過(guò)程的過(guò)濾器負(fù)責(zé)將輸出提供給客戶機(jī)。
web.xml中對(duì)Filter的標(biāo)準(zhǔn)配置













注:默認(rèn)情況下,過(guò)濾器是按照配置文件中添加的順序應(yīng)用于收到的數(shù)據(jù)。
激活器servlet
要傳遞參數(shù)的時(shí)候最好使用form進(jìn)行傳參,如果使用鏈接的話當(dāng)中文字符的時(shí)候過(guò)濾器轉(zhuǎn)碼是不會(huì)起作用的,還有就是頁(yè)面上form的method也要設(shè)
置為post,不然過(guò)濾器也起不了作用。
過(guò)濾器的工作方式:
一:request過(guò)濾器
請(qǐng)求直接從客戶端發(fā)過(guò)來(lái)
通過(guò)在<dispatcher>元素中指定值REQUEST,或者不寫(xiě)任何<dispatcher>元素的方式指定
二:forward過(guò)濾器
web組件使用forward()調(diào)用匹配<url-pattern>或<servlet-name>。
這通過(guò)在<dispatcher>元素中設(shè)定值FORWARD指定
三:include過(guò)濾器
web組件使用include()調(diào)用匹配<url-pattern>或<servlet-name>。
這通過(guò)在<dispatcher>元素中設(shè)置值INCLUDE指定
四:error過(guò)濾器
請(qǐng)求使用在“錯(cuò)誤處理”中描述的錯(cuò)誤機(jī)制進(jìn)行處理,讓錯(cuò)誤資源匹配<url-pattern>。這通過(guò)在<dispatcher>元素中設(shè)置值ERROR指定


















對(duì)于上面配置,當(dāng)出現(xiàn)空指針,或空指針時(shí),就會(huì)跳轉(zhuǎn)到error.jsp頁(yè)面,在訪問(wèn)error.jsp頁(yè)面前,由于對(duì)error.jsp進(jìn)行了過(guò)濾,先執(zhí)行ErrorPageFilter,然后轉(zhuǎn)向error.jsp
如果我們實(shí)際訪問(wèn)時(shí),如果這個(gè)頁(yè)面中有response.sendError(500,"出錯(cuò)了!"),或者手動(dòng)拋出空指針時(shí),;那么該錯(cuò)誤頁(yè)面仍然會(huì)被調(diào)用,過(guò)濾器也會(huì)工作。
過(guò)濾器的實(shí)踐:
一:統(tǒng)一過(guò)濾HTTP請(qǐng)求(響應(yīng))頭(如:使瀏覽器不緩存頁(yè)面的過(guò)濾器 )
二、權(quán)限控制(對(duì)不同角色在系統(tǒng)中跳轉(zhuǎn)進(jìn)行檢查控制)
三、字符編碼的過(guò)濾器 (對(duì)post數(shù)據(jù)起效)
四、資源保護(hù)過(guò)濾器 (檢測(cè)用戶是否登陸的過(guò)濾器 )
五、阻塞請(qǐng)求
參考文獻(xiàn):http://www.vipcn.com/wangluobiancheng/JSP/servletheJSPguoluqiFilter.html