本篇文章主要介紹了JavaWeb之Filter過濾器詳解,實例分析了JavaWeb之Filter過濾器的使用技巧,非常具有實用價值,需要的朋友可以參考下。
原本計劃這篇來總結JSP,由於JSP的內容比較多,又想著晚上跑跑步減減肥,所以今天先介紹Filter以及它的使用舉例,這樣的話還有些時間可以運動。言歸正傳,過濾器從字面理解她的話有攔網、過濾的功能,可以算是JavaWeb的攔精靈。
一、由來
客戶端發起請求,那伺服器不能什麼請求都做出回應,做攔截處理,不僅能減輕伺服器的壓力,還能保護資料的安全,同樣服務端做出回應給客戶端時有時也需要進行過濾,例如我們常見的圖片新增浮水印。為了處理這些問題,於是過濾器出現了。有時不僅對請求與回應進行一層的過濾,可能會過濾多層,所以提出了濾鏡鏈(FilterChain)的概念.
二、使用
在使用它之前先熟悉下它的作用的地方。過濾器作用在請求Request到達Servlet之前以及回應Response到達瀏覽器之前會依序經過過慮鏈。有些類似asp.net中的httpmodule.使用Filter主要是實作javax.servlet.filter介面。查看API可看到有3個方法。
1.public void init(FilterConfig filterConfig) throws ServletException
由Web 容器呼叫,指示將放入服務中的篩選器。 servlet 容器只在實例化過濾器之後呼叫一次 init 方法。在要求過濾器做任何過濾工作之前,init 方法必須成功完成。如果 init 方法拋出 ServletException或沒有在 Web 容器定義的時間段內傳回,則 Web 容器無法將篩選器放入服務中。這個和Servlet的生命週期有點類似,也是只初始化一次,destroy()也是執行一次。
2.public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException
#因為對鏈末尾的某個某個地方資源的客戶端請求而透過鏈結傳遞請求/回應對時,容器都會呼叫Filter 的doFilter 方法。傳入此方法的 FilterChain 允許 Filter 將請求和回應傳遞到鏈中的下一個實體。
此方法的典型實作遵循下列模式:
1. 檢查請求
2. 選擇性地將具有自訂實作的請求物件包裝到用於輸入過濾的過濾器內容或頭中
3. 選擇性地將帶有自訂實現的響應對象包裝到用於輸出過濾的過濾器內容或頭中
4. a) 既可以使用FilterChain 物件(chain.doFilter()) 呼叫鏈中的下一個實體,
4. b) 也可以不將請求/回應對傳遞給過濾器鏈中的下一個實體,從而阻塞請求處理
#5. 在呼叫過濾器鏈中的下一個實體之後直接設定回應上的頭。
3.public void destroy()
由 Web 容器呼叫,指示將從服務中取出的篩選器。此方法僅在過濾器的 doFilter 方法中的所有執行緒都已退出之後呼叫一次,或在過了超時期之後呼叫。在呼叫此方法之後,Web 容器不會再對此過濾器實例呼叫 doFilter 方法。此方法為過濾器提供了清除持有的所有資源(例如記憶體、檔案句柄和執行緒)的機會,並確保任何持久性狀態都與記憶體中該過濾器的當前狀態保持同步。
三、案例
使用過濾器的地方有很多,這裡就不一一舉例,下面的demo在上篇部落格中HelloWorld專案的基礎上實現防盜鏈的功能,以此體會Filter的使用。
1.準備
在HelloWolrd專案中新增一個資料夾,在資料夾中放入兩個圖片一個err.png 一個test.png,兩個圖如下
2.建立Filter
這裡也沒新建Filter包,直接在上一部落格中的com.test.cyw套件中建立Filter檔案MyFilter,應該是建立一個套件專門管理Filter類的額,這裡只是做測試。建立完成之後可以看到MyFilter繼承Filter。
public class MyFilter implements Filter
3.在doFilter中實作防盜鏈
package com.test.cyw; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.*; /*@WebFilter("/MyFilter")*/ public class MyFilter implements Filter { public MyFilter() { } public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req=(HttpServletRequest)request; HttpServletResponse res=(HttpServletResponse)response; String referer=req.getHeader("referer");//链接来源地址 if(referer==null||!referer.contains(req.getServerName())) { req.getRequestDispatcher("/Images/err.png").forward(req, res); return; } chain.doFilter(req, res); } public void init(FilterConfig fConfig) throws ServletException { } }
4.Filter配置
#上面只是創建了一個類別實作了Filter接口,如何讓Tomcat知道呢,這和Servlet類似,需要在Web.xml中配置。和配置servlet有點相同。
<filter> <filter-name>MyFilter</filter-name> <filter-class>com.test.cyw.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>MyFilter</filter-name> <url-pattern>/Images/*</url-pattern> </filter-mapping>
5.測試
新建一個test.jsp文件,在jsp中顯示img,可以正常顯示
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <img alt="防盗链" src="Images/test.png" width="400"> </body> </html>
如果直接在瀏覽器輸入test.png的位址,則會顯示err.png
##四、遇到的問題
開始的時候由於地址錯誤,導致Google瀏覽器test.jsp中顯示的也是err.png的圖片,但當我換過來時刷新頁面還是沒變,這讓我很納悶。有時候將Tomca重啟也不行,試了好幾次都是這樣,實在不行了用IE試了下沒想到顯示是正確的,原來谷歌瀏覽器有五、總結
Filter用處很多,網路上也有好多的例子,做專案時可以先實作一些常用的例如水印,等用的時候只要設定xml就能解決,很方便。以上是JavaWeb之Filter過濾器詳細介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!