一 砸逊、過濾器(filter)
1、概要
在源數(shù)據(jù)和目的數(shù)據(jù)之間起過濾作用的中間組件
當(dāng)web容器接收到一個對資源的請求時掌逛,它將判斷是否有過濾器與這個資源相關(guān)师逸,如果有拦盹,那么容器將請求交給過濾器進行處理殊霞。在過濾器中洲尊,可以改變請求的內(nèi)容或者重新設(shè)置請求的報頭信息竿刁,然后再將請求發(fā)送給目標(biāo)資源。當(dāng)目標(biāo)資源對請求作出響應(yīng)時神得,容器同樣會將響應(yīng)轉(zhuǎn)發(fā)給過濾器锌介。然后發(fā)送到客戶端**
2令哟、web.xml 中聲明的每個 filter 在每個虛擬機中僅僅只有一個實例心傀。
Web 容器啟動時屈暗,即會根據(jù) web.xml 中聲明的 filter 順序依次實例化這些 filter拆讯。
- 初始化
Web 容器調(diào)用 init(FilterConfig) 來初始化過濾器脂男。容器在調(diào)用該方法時,向過濾器傳遞 FilterConfig 對象种呐,F(xiàn)ilterConfig 的用法和 ServletConfig 類似宰翅。利用 FilterConfig 對象可以得到 ServletContext 對象,以及在 web.xml 中配置的過濾器的初始化參數(shù)爽室。在這個方法中汁讼,可以拋出 ServletException 異常,通知容器該過濾器不能正常工作阔墩。此時的 Web 容器啟動失敗嘿架,整個應(yīng)用程序不能夠被訪問。實例化和初始化的操作只會在容器啟動時執(zhí)行啸箫,而且只會執(zhí)行一次耸彪。
- doFilter
doFilter 方法類似于 Servlet 接口的 service 方法。當(dāng)客戶端請求目標(biāo)資源的時候忘苛,容器會篩選出符合 filter-mapping 中的 url-pattern 的 filter蝉娜,并按照聲明 filter-mapping 的順序依次調(diào)用這些 filter 的 doFilter 方法唱较。在這個鏈?zhǔn)秸{(diào)用過程中,可以調(diào)用 chain.doFilter(ServletRequest, ServletResponse) 將請求傳給下一個過濾器(或目標(biāo)資源)召川,也可以直接向客戶端返回響應(yīng)信息南缓,或者利用 RequestDispatcher 的 forward 和 include 方法,以及 HttpServletResponse 的 sendRedirect 方法將請求轉(zhuǎn)向到其它資源荧呐。需要注意的是汉形,這個方法的請求和響應(yīng)參數(shù)的類型是 ServletRequest 和 ServletResponse,也就是說倍阐,過濾器的使用并不依賴于具體的協(xié)議获雕。
- 銷毀
Web 容器調(diào)用 destroy 方法指示過濾器的生命周期結(jié)束。在這個方法中收捣,可以釋放過濾器使用的資源届案。
3、接口相關(guān)接口介紹
1罢艾、Filter接口
- init(FilterConfig filterConfig)
初始化過濾器楣颠。filterconfig用來獲取ServletContext,初始化參數(shù)。 - doFilter(ServletRequest request,ServletResponse response,FilterChain chain);
實現(xiàn)過濾功能咐蚯⊥觯可以調(diào)用chain.doFilter(request,response)方法將請求傳遞給下一個過濾器或者目標(biāo)資源,也可以直接向客戶端返回響應(yīng)信息春锋。 - destory()
結(jié)束過濾器的聲明周期矫膨。
2、FilterConfig接口
- getInitParameter(String name)
返回名為name的初始化參數(shù)的值 - getInitParameterNames()
返回所有初始化參數(shù)的名字的枚舉集合期奔。 - getServletContext()
返回Servlet上下文對象的引用
3侧馅、FilterChain接口
- doFilter(ServletRequest request,ServletResponse response)
調(diào)用該方法將使過濾器鏈中的下一個過濾器被調(diào)用,如果該方法時過濾器鏈中最后一個過濾器呐萌,那么目標(biāo)資源被調(diào)用
4馁痴、簡單使用
4.1、Filter開發(fā)分為2步:
編寫java類實現(xiàn)Filter接口肺孤,并實現(xiàn)其doFilter方法罗晕。
在web.xml 文件中使用和元素對編寫的filter類進行注冊,并設(shè)置它所能攔截的資源赠堵。
4.2小渊、示例代碼
- java代碼
public class CharsetFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { // 對request、response進行一些預(yù)處理 request.setCharacterEncoding("utf-8"); response.setContentType("text/html ; charset=utf-8"); //繼續(xù)攔截 filterChain.doFilter(request, response); } @Override public void destroy() { }
}
2. 在web.xml中注冊
```xml
<filter-name>charset-filter</filter-name>
<filter-class>com.werner.demo.filter.CharsetFilter</filter-class>
<init-param>
<param-name>charset</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>enable</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>charset-filter</filter-name>
<url-pattern>/servlet/*</url-pattern>
<url-pattern>/l</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<servlet>
<servlet-name>Filter</servlet-name>
<servlet-class>com.werner.demo.servlet.HttpServletFilter</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Filter</servlet-name>
<url-pattern>/l</url-pattern>
</servlet-mapping>
- 說明:
-
<filter>
:配置 Filter 名稱茫叭,實現(xiàn)類以及初始化參數(shù)酬屉。可以同時配置多個初始化參數(shù)杂靶。 -
<filter-mapping>
:配置什么規(guī)則下使用這個Filter 梆惯。- <url-pattern> :`配置url的規(guī)則酱鸭,可以配置多個,也可以使用通配符()垛吗。例如 /jsp/ 適用于本ContextPath下以“/jsp/ ”開頭的所有servlet路徑凹髓, *.do 適用于所有以“ .do”結(jié)尾的servlet路徑。
-
<dispatcher> :
配置到達servlet的方式怯屉,可以同時配置多個蔚舀。有四種取值:REQUEST、FORWARD锨络、ERROR赌躺、INCLUDE。如果沒有配置羡儿,則默認(rèn)為REQUEST礼患。它們的區(qū)別是:- REQUEST :表示僅當(dāng)直接請求servlet時才生效。
- FORWARD :表示僅當(dāng)某servlet通過forward轉(zhuǎn)發(fā)到該servlet時才生效掠归。
{0}. INCLUDE :Jsp中可以通過<jsp:include/>
請求某servlet缅叠, 只有這種情況才有效。
{0}. ERROR :Jsp中可以通過<%@page errorPage="error.jsp" %>
指定錯誤處理頁面虏冻,僅在這種情況下才生效肤粱。
-
5、Filter應(yīng)用場景
1厨相、統(tǒng)一POST請求中文字符編碼的過濾器 2领曼、控制瀏覽器緩存頁面中的靜態(tài)資源的過濾器
有些動態(tài)頁面中引用了一些圖片或css文件以修飾頁面效果,這些圖片和css文件經(jīng)常是不變化的蛮穿,所以為減輕服務(wù)器的壓力庶骄,可以使用filter控制瀏覽器緩存這些文件,以提升服務(wù)器的性能绪撵。
3瓢姻、使用Filter實現(xiàn)URL級別的權(quán)限認(rèn)證
在實際開發(fā)中我們經(jīng)常把一些執(zhí)行敏感操作的servlet映射到一些特殊目錄中祝蝠,并用filter把這些特殊目錄保護起來音诈,限制只能擁有相應(yīng)訪問權(quán)限的用戶才能訪問這些目錄下的資源。從而在我們系統(tǒng)中實現(xiàn)一種URL級別的權(quán)限功能绎狭。
4细溅、實現(xiàn)用戶自動登陸
首先,在用戶登陸成功后儡嘶,發(fā)送一個名稱為user的cookie給客戶端喇聊,cookie的值為用戶名和md5加密后的密碼。編寫一個AutoLoginFilter蹦狂,這個filter檢查用戶是否帶有名稱為user的cookie誓篱,如果有朋贬,則調(diào)用dao查詢cookie的用戶名和密碼是否和數(shù)據(jù)庫匹配,匹配則向session中存入user對象(即用戶登陸標(biāo)記)窜骄,以實現(xiàn)程序完成自動登陸锦募。
5、認(rèn)證Filter
6邻遏、日志和審核Filter
7糠亩、圖片轉(zhuǎn)換Filter
8、數(shù)據(jù)壓縮Filter
8准验、密碼Filter
9赎线、令牌Filter
二、監(jiān)聽器
2.1糊饱、說明
Servlet API中定義了8個監(jiān)聽器接口垂寥,可以用于監(jiān)聽ServletContext,HttpSession,ServletRequest對象的生命周期事件。
- ServletContextListener 監(jiān)聽Servlet上下文對象初始化或者被銷毀
- ServletContextAttributeListener 監(jiān)聽Servlet上下文中的屬性列表的變化
- HttpSessionListener 監(jiān)聽Session生命周期
- HttpSessionActionListener 監(jiān)聽session被鈍化或者激活
- HttpSessionAttributeListener 監(jiān)聽Session屬性列表發(fā)生的變化
- HttpSessionBindingListener 監(jiān)聽Session中是否有對象綁定或者刪除另锋,該對象要實現(xiàn)這個接口
- ServletRequestListener 監(jiān)聽ServletRequest對象生命周期
- ServletRequestAttributeListener 監(jiān)聽ServletRequest屬性列表發(fā)生的變化
2.2矫废、詳細解釋
- ServletContextListener 監(jiān)聽ServletContext的啟動或者銷毀
- contextInitialized(ServletContextEvent sce)
當(dāng)web應(yīng)用程序初始化進程正開始時,web容器調(diào)用這個方法砰蠢,該方法將在所有的過濾器和Servlet初始化之前被調(diào)用蓖扑。contextDestroyed(ServletContextEvent sce)當(dāng)Servlet上下文將要關(guān)閉時,Web容器調(diào)用這個方法台舱,該方法在所有Servlet和和過濾器銷毀之后被調(diào)用律杠。
例子: 在Web應(yīng)用程序啟動時初始化DataSource對象,然后將其方法ServletContext中 數(shù)據(jù)庫支持更換 - HttpSessionBindingListener竞惋,(無序配置)
如果一個對象實現(xiàn)了HttpSessionBindingListener接口柜去,當(dāng)這個對象被綁定的Session或者從Session中被刪除時,Servlet容器就會通知這個對象拆宛。- valueBound(HttpSessionBindingEvent event)
當(dāng)對象正在被綁定到Session中嗓奢,Servlet容器調(diào)用這個方法通知該對象 - valueUnBound(HttpSessionBindingEvent event)
- valueBound(HttpSessionBindingEvent event)