⑧javaWeb之在例子中学习(过滤器Filter)
前言
本系列 Servlet & JSP 學習系列[傳送門]逐漸到了中期了,希望大家喜歡我寫的,總結的點點滴滴-
今天我們來講講過濾器
你們的支持是我寫博客的動力哦。
最近買了兩本書,覺得大二了。每個月的零花錢中買幾本書,一年也能買二三十本。不亦樂乎!分享下
?
? ? ? ? ? ??
雖然看不懂,先看吧。至少不虧,以后溫故知新.
Fitler(過濾器)
過濾器filter是攔截請求,并對傳給請求資源的ServletRequest 或 ServletResponse 進行處理的一個對象。可以用于登錄,加密和解密,會話檢查,圖片轉換等等
?
過濾器執行機制圖:
Filter API :?http://docs.oracle.com/javase/6/docs/api/
Filter詳解
Filter接口的構成:
????? 所有的Filter類都必須實現javax.servlet.Filter接口。這個接口含有3個過濾器類必須實現的方法:
?
?????? ? ①init(FilterConfig):這是Filter的初始化方法,Servlet容器創建Filter實例后將調用這個方法。在這個方法中可以讀取web.xml文件中Filter的初始化參數
??????? ?②doFilter(ServletRequest,ServletResponse,FilterChain):?這個方法完成實際的過濾操作,當客戶請求訪問于Filter關聯的URL時,Servlet容器將先調用Filter的doFilter方法。FilterChain參數用于訪問后續Filters
????? ? ?③destroy():? Servlet容器在銷毀Filter實例前調用該方法,這個方法中可以釋放Filter占用的資源
?
? ? ? ?配置Filter(下面例子用的是注釋配置)
?
<filter> <filter-name>enconfigFilter</filter-name> <filter-class>com.filter.EnconfigFilter</filter-class> <init-param> <param-name>enconfig</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>enconfigFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>?
?
? ? ? ?其中: ??
??????? filter-name?? 指定過濾器的名字
??????? filter-class????指定過濾器的類名
??????? init-param????為過濾器實例提供初始化參數,可以有多個
??????? url-pattern?? 指定和過濾器關聯的URL,為”/*”表示所有URL
?
圖片保護過濾器
咱們用ImageProtetorFilter來保護咱們的圖片,防止地址欄中直接輸入圖片URL 來下載圖片。
?
小小的原理:
過濾器通過查看HTTP 標頭的referer的值進行工作。值為空表示當前請求沒有相當的引用頁。而值為空,說明請求在引用頁,自然圖片在jsp里面供認看與下載。
小朽嘗試:
①包結構
② ImageProtector類
doFilter實現了,獲取標頭→判斷→然后拋異常
package sedion.jeffli.filter;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.HttpServletRequest;/*** * @author Jeff Li**/ @WebFilter(filterName = "ImageProtetorFilter",urlPatterns={"*.png","*.jpg","*.gif"}) public class ImageProtector implements Filter{@Overridepublic void destroy() {// TODO Auto-generated method stub }@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {System.out.println("ImageProtetorFilter");HttpServletRequest httpServletR = (HttpServletRequest)request;String referrer = httpServletR.getHeader("referer");System.out.println("referrer:"+referrer);if(referrer != null){chain.doFilter(request, response);}else{throw new ServletException("Image not available");}}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// TODO Auto-generated method stub }}
③JSP 頁面加入
<img alt="logo" src="logo.jpg">?
小朽看效果說話:
①當直接在火狐中,打開url:http://localhost:8080/filterTest/logo.jpg
頁面出現了?HTTP Status 500 - Image not available
打開小蜜蜂(firebug),查看網絡,發現沒有referer請求頭信息
②當直接在火狐中,打開url:http://localhost:8080/filterTest/index.jsp
頁面自然出現了圖片。
打開小蜜蜂(firebug),查看網絡
?
下載過濾器
顧名思義,計算某個資源下載了多少次,或知道某些東石受歡迎程度。自然這個必不可少。
Question and Solving:
我們將值保存在一個屬性文件中,并且多個線程可以同時訪問一個過濾器,因此就有一個線程安全性的問題需要解決。用戶請求資源讀取相應屬性值,將它贈一個并存回新值。如果第一個線程完成任務前,又有第二個用戶請求同一個資源,怎么辦?同步讀寫值的代碼似乎不是個好方法,涉及到擴展性的問題。
我們利用Queue 和 Executor 解決這個線程的問題。所有進來的請求都在一個線程Executor隊列中放置一項任務。放置任務比較快,因為這是一個異步的操作。由于只有使用一個Executor一個線程,因此消除了多線程訪問該屬性文件的可能。
小朽嘗試:
就加個DownloadCounterFilter,啟動就好。
package sedion.jeffli.filter;import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.Properties; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;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.HttpServletRequest; /*** * @author Jeff Li**/@WebFilter(filterName="DownloadCounterFilter",urlPatterns={"/*"}) public class DownloadCounterFilter implements Filter{ExecutorService executorService = Executors.newSingleThreadExecutor();Properties downloadLog;File logFile;@Overridepublic void destroy() {executorService.shutdown();}@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {HttpServletRequest httpServletRequest = (HttpServletRequest) request;final String uri = httpServletRequest.getRequestURI();executorService.execute(new Runnable() {@Overridepublic void run() {String property = downloadLog.getProperty(uri);if(property == null){downloadLog.setProperty(uri, "1");}else{int count = 0;try {count = Integer.parseInt(property);} catch (NumberFormatException e) {}count++;downloadLog.setProperty(uri, Integer.toString(count));}try {downloadLog.store(new FileWriter(logFile), "");} catch (Exception e) {}}});chain.doFilter(request, response);}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("DownloadCounterFilter");String appPath = filterConfig.getServletContext().getRealPath("/");logFile = new File(appPath,"downloadLog.txt");if(!logFile.exists()){try {logFile.createNewFile();} catch (IOException e) {e.printStackTrace();}}downloadLog = new Properties();try {downloadLog.load(new FileReader(logFile));} catch (IOException e) {e.printStackTrace();}}}
小朽分析下:
String appPath = filterConfig.getServletContext().getRealPath("/");logFile = new File(appPath,"downloadLog.txt");if(!logFile.exists()){try {logFile.createNewFile();} catch (IOException e) {e.printStackTrace();}}
項目路徑下:tomcat_dir/filterTest/ 如果沒有文件downloadLog.txt,初始化生成。當訪問項目有關文件,則會記錄到這個property文件中。
小朽看效果:
打開tomcat_dir/filterTest/downloadLog.txt
# #Thu Mar 20 12:39:02 CST 2014 /filterTest/logo.jpg=3 /filterTest/=1 /filterTest/index.jsp=2
總結?
寄讀者,寄知識來源
讀者,你好!你我不相識,謝謝你們支持。只有記錄點滴,我的夢想會越來越接近。共勉!
知識來源 http://book.douban.com/doulist/3575997/
轉載于:https://www.cnblogs.com/Alandre/p/3613457.html
總結
以上是生活随笔為你收集整理的⑧javaWeb之在例子中学习(过滤器Filter)的全部內容,希望文章能夠幫你解決所遇到的問題。