19-过滤器
一、過濾器入門
1. 概念:
??? Filter 過濾器,又稱攔截器
??? 實現 Filter 接口的類我們稱之為 Filter (過濾器或攔截器)
??? Filter能對用戶訪問的資源進行攔截
???
??? 在Filter里面可以只用 request獲得請求消息? 用response寫入響應消息
??? chain.doFilter(request, response) 方法放行? 目標Servlet使用的是同一個請求和響應
??? doFilter 方法后面的代碼會執行,在目標Servlet 返回響應后執行, 也可以使用同一個請求和響應
?
2. 實現:
??? 1) 寫一個類實現 Filter 接口 , 在doFilter 方法中寫功能代碼
??? public class Filter1 implements Filter {
?????????? public void doFilter(ServletRequest request, ServletResponse response,
?????????? FilterChain chain) throws IOException, ServletException {
?????? ??? System.out.println("before");
?????????? chain.doFilter(request, response);
?????? ??? System.out.println("after");
??? }
??? 2) 在web.xml中配置Filter攔截的資源路徑
??? <filter>
?????? <filter-name>filter1</filter-name>
?????? <filter-class>cn.itcast.filter.Filter1</filter-class>
??? </filter>
??? <filter-mapping>
?????? <filter-name>filter1</filter-name>
?????? <url-pattern>/*</url-pattern>
??? </filter-mapping>
?
3. Filter 鏈
??? 可以針對某一個url配置多個Filter, 這些Filter就會組成一個Filter鏈, 用FilterChain對象表示
??? FilterChain對象的doFilter方法作用就是讓Filter鏈上的當前攔截器放行,請求進入下一個Filter
?
??? response 的中文編碼問題, 只能在response.getWriter() 第一次被調用之前指定編碼才有效
??? 一旦指定了編碼,當前Filter鏈和目標Servlet使用的response都是同一個編碼,因為用的本來就是一個
??? response
?
4. Filter 與 Servlet
??? Filter 就像一個特殊的Servlet
??? Filter 在web容器啟動是就初始化
??? Filter 可以實現攔截功能,因為有個 FilterChain 對象,有個 doFilter方法可以實現對訪問資源的放行
二、 Filter細節
1. Filter 的生命周期
??? 實現Filter的init和destroy方法就可以觀察Filter的聲明周期
??? web容器啟動時,會讀web.xml文件,將所有的Filter都初始化
??? Filter對象創建后會駐留在內存,當web應用移除或服務器停止時才銷毀
?
Filter鏈中所有的Filter的攔截順序?? 按照 在 web.xml 文件中的配置的先后順序來進行攔截
?
2. 獲得 Filter 的初始化參數
??? 在 web.xml 文件中為Filter 配置初始化參數
??? <init-param>
?????? <param-name>name</param-name>
?????? <param-value>xxxx</param-value>
??? </init-param>
??? 在 init 方法中讀取配置文件
??? public void init(FilterConfig filterConfig) throws ServletException {
?????? String name = filterConfig.getInitParameter("name");
??????
??? }
?
3. 攔截 html 頁面
1) 文件緩存
?由于html頁面的url是沒有在 web.xml 文件中配置的 服務器會調用DefaultServlet
在DefaultServlet 中會檢查文件的修改時間, 如果沒有修改則發送 304頭
這樣就會導致過濾器也被緩存
可以通過發送 200 狀態碼,但是 html 頁面的數據仍然得不到讀取
?
2) html 頁面亂碼
在 Filter 和 Html 中指定編碼為 utf-8 , 這樣會導致 html 頁面中文亂碼
原因是 html 頁面數據會通過 DefaultServlet 發送
查看 web.xml 文件 發現DefaultServlet默認使用 gbk編碼
修改配置 加初始化參數
<init-param>
????? <param-name>fileEncoding</param-name>
????? <param-value>utf-8</param-value>
?</init-param>
?
4. Filter攔截方式
Filter的dispatcher元素有4種取值, 分別代表四種攔截方式
REQUEST 攔截直接的請求方式
INCLUDE 攔截頁面包含的訪問方式
FORWARD 攔截請求轉發訪問方式
ERROR 攔截出錯頁面的訪問方式
?
5. filter-mapping元素配置
攔截的url地址可以使用 /*? *.擴展名
<filter-mapping> 元素中可以配置多個地址 用于攔截多個url或servlet
對于多個條件都符合的url, filter會進行多次攔截
?
三、 過濾器案例
1. 緩存
禁止瀏覽器緩存所有動態頁面
response.setDateHeader("Expires",-1);
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragma","no-cache");
?
強制瀏覽器緩存所有的靜態頁面 html jpg css
String uri = request.getRequestURI();
String time = null;
if(uri.endsWith(".html"))
??? time = config.getInitParameter("html");
else if(uri.endsWith(".jpg"))
??? time = config.getInitParameter("jpg");
long l = Long.parseLong(time);
response.setDateHeader("Expires",System.currentTimeMillis() + l);
?
2. 實現用戶自動登陸
1)在用戶登陸成功后,發送一個名稱為user的cookie給客戶端,cookie的值為用戶名和md5加密后的密碼
2)編寫過濾器檢查用戶是否帶名為user的cookie來,如果有,檢查用戶名和密碼做自動登陸
?
核心思路:
用戶登陸后找LoginServlet , LoginServlet中做登陸,如果登陸成功, 獲得用戶選擇的自動登陸時間
創建一個新的cookie 將用戶名和密碼用 “_”連接作為value,autoLogin作為name
設置cookie 的有效路徑 request.getContextPath() 作用于整個web應用
設置cookie的有效時間為 autologintime
發送 cookie
?
寫一個過濾器,對全站的資源進行攔截, 檢查用戶發送的cookie有沒有一個名為autologin的
如果有 取出用戶名和密碼 再次做登陸處理 如果登陸成功, 將 user 存入session ,放行
?
出于安全性考慮, cookie 中的密碼應該進行 md5 加密
?
3. 統一全站字符編碼
response和request的post的方式好辦
// 解決全站的亂碼問題? request response
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");? // 只對 post 方式起作用,對get方式不起作用
?
對于request的get方式需要手工轉換,此時就需要用到 包裝設計模式decorator
包裝 getParameter方法
?
4. 為全站添加頁眉和頁腳
添加用戶模塊
?
5. 發送壓縮后的響應數據
??? 給 IE 瀏覽器會送的數據 需要進行gzip 壓縮? 訪問速度快 省點瀏覽
??? 在最后將數據打給瀏覽器的時候, 將 response 中的數據全部壓縮
??? 在過濾器放行的時候傳入一個 假的 response 提供緩沖區, 這樣后面的資源都會寫入我的緩沖區
??? 緩沖區滿了 或者 請求快結束的時候 將緩沖區的數據壓縮后寫入 真的 response??
???
??? j2se 提供了一個流GZIPOutputStream 用于 gzip壓縮
??? j2se 提供了一個流 ZIPOutputStream 用于 zip 壓縮
?
6. 跟蹤用戶上次訪問時間
?
7. 統計站內各個頁面的訪問次數
?
8. 實現某些資源只能被某些ip訪問
?
9. 實現防盜鏈功能
??? 針對所有的下載頁面
?
10. 實現html標簽轉義、過濾敏感詞匯
?
總結
- 上一篇: 丘吉尔坦克到底有多狠
- 下一篇: 图形放大和缩小的知识点在火箭中的应用?