Tomcat Filter 自己动手实现
Filter 簡介
Filter也稱之為過濾器,它是Servlet技術中最實用的技術,Web開發人員通過Filter技術,對web服務器管理的所有web資源:例如Jsp, Servlet, 靜態圖片文件或靜態 html 文件等進行攔截,從而實現一些特殊的功能。例如實現URL級別的權限訪問控制、過濾敏感詞匯、壓縮響應信息等一些高級功能。
它主要用于對用戶請求進行預處理,也可以對HttpServletResponse進行后處理。使用Filter的完整流程:Filter對用戶請求進行預處理,接著將請求交給Servlet進行處理并生成響應,最后Filter再對服務器響應進行后處理。
Filter功能
在HttpServletRequest到達 Servlet 之前,攔截客戶的HttpServletRequest 。根據需要檢查HttpServletRequest,也可以修改HttpServletRequest 頭和數據。在HttpServletResponse到達客戶端之前,攔截HttpServletResponse 。根據需要檢查HttpServletResponse,也可以修改HttpServletResponse頭和數據。
如何借助Filter實現攔截功能
Filter接口中有一個doFilter方法,當開發人員編寫好Filter,并配置對哪個web資源進行攔截后,Web服務器每次在調用web資源的service方法之前,都會先調用一下filter的doFilter方法,因此,在該方法內編寫代碼可達到如下目的:
調用目標資源之前,讓一段代碼執行。是否調用目標資源(即是否讓用戶訪問web資源)。web服務器在調用doFilter方法時,會傳遞一個filterChain對象進來,filterChain對象是filter接口中最重要的一個對象,它也提供了一個doFilter方法,開發人員可以根據需求決定是否調用此方法,調用該方法,則web服務器就會調用web資源的service方法,即web資源就會被訪問,否則web資源不會被訪問。
**下面根據tomcat中的 filter 自己實現一個Filter
參考:Tomcat Filter 源碼分析
Filter使用設計模式中的責任鏈設計模式**
手寫 Filter過濾器 源碼實現
先看下有哪些類,如下圖:
1. Filter 接口
Filter.java
public interface Filter {public void doFilter(Request req, Response res, FilterChain filterChain); }2. 過濾鏈實現類
FilterChain.java
這個類是過濾器鏈的核心類
import java.util.ArrayList; import java.util.List;public class FilterChain{//目標servletprivate Servlet servlet;//將要執行的過濾器下標(過濾器鏈)private int pos = 0;//存儲過濾器的容器(tomcat中使用的是一個數組進行存儲的)private List<Filter> list = new ArrayList<>();public void doFilter(Request req, Response res) {//判斷是否還有要執行的filterif(pos<list.size()){//每次調用過濾器鏈的doFilter時,都要將pos坐標+1//注意pos++的位置,如果調用完doFilter在pos++ 就出現死循環了list.get(pos++).doFilter(req, res, this);}else{//如果所有的過濾器都執行完成則執行servletgetServlet().service(req, res);}}//向過濾器鏈中添加過濾器public void addFilter(Filter filter){list.add(filter);}//設置servletpublic void setServlet(Servlet servlet) {this.servlet = servlet;}public Servlet getServlet() {return servlet;} }3. 模擬 web 中的 Servlet
Servlet.java
public class Servlet {public void service(Request req, Response res){System.out.println("service ok----------");} }4. 自定義的過濾器
EncodeFilter.java
模擬實現編碼轉換過濾器
public class EncodeFilter implements Filter{@Overridepublic void doFilter(Request req, Response res, FilterChain chain) {//在 servlet 之前執行System.out.println("encode start ...");chain.doFilter(req, res);//在 servlet 之后執行System.out.println("encode end ...");}}LogFilter.java
模擬實現日志過濾器
public class LogFilter implements Filter{@Overridepublic void doFilter(Request req, Response res, FilterChain chain) {//在 servlet 之前執行System.out.println("log start ...");chain.doFilter(req, res);//在 servlet 之后執行System.out.println("log end ...");}}5. 模擬 servlet 中 request 和 response 對象
這里Request類和Response類,沒有實現任何方法,只是為模擬Servlet中的參數而創建的類。
Request.java
public class Request {}Response.java
public class Response {}6. 啟動方法
Main.java
public class Main {public static void main(String[] args) {FilterChain chain = new FilterChain();//設置要執行的Servletchain.setServlet(new Servlet());//根據url-pattern的匹配規則 向 FilterChain中添加過濾器//這些Filterchain.addFilter(new LogFilter());chain.addFilter(new EncodeFilter());//執行chain.doFilter(new Request(), new Response());} }本人簡書blog地址:http://www.jianshu.com/u/1f0067e24ff8????
點擊這里快速進入簡書
GIT地址:http://git.oschina.net/brucekankan/
點擊這里快速進入GIT
總結
以上是生活随笔為你收集整理的Tomcat Filter 自己动手实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用DelayQueue 和 Futur
- 下一篇: Servlet 是线程安全的吗?