過濾器(Filter)

1 什么是過濾器

過濾器JavaWeb三大組件之一,它與Servlet很相似!不它過濾器是用來攔截請求的,而不是處理請求的。

當用戶請求某個Servlet時,會先執行部署在這個請求上的Filter,如果Filter“放行”,那么會繼承執行用戶請求的Servlet;如果Filter不“放行”,那么就不會執行用戶請求的Servlet。

其實可以這樣理解,當用戶請求某個Servlet時,Tomcat會去執行注冊在這個請求上的Filter,然后是否“放行”由Filter來決定。可以理解為,Filter來決定是否調用Servlet!當執行完成Servlet的代碼后,還會執行Filter后面的代碼。

?

其實過濾器與Servlet很相似,我們回憶一下如果寫的第一個Servlet應用!寫一個類,實現Servlet接口!沒錯,寫過濾器就是寫一個類,實現Filter接口。

public class HelloFilter implements Filter {public void init(FilterConfig filterConfig) throws ServletException {}public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {System.out.println("Hello Filter");}public void destroy() {}
}
  <filter><filter-name>helloFilter</filter-name><filter-class>cn.itcast.filter.HelloFilter</filter-class></filter><filter-mapping><filter-name>helloFilter</filter-name><url-pattern>/index.jsp</url-pattern></filter-mapping>
過濾器的生命周期

?

我們已經學習過Servlet的生命周期,那么Filter的生命周期也就沒有什么難度了!

?

   init(FilterConfig):在服務器啟動時會創建Filter實例,并且每個類型的Filter只創建一個實例,從此不再創建!在創建完Filter實例后,會馬上調用init()方法完成初始化工作,這個方法只會被執行一次;

?

  doFilter(ServletRequest req,ServletResponse res,FilterChain chain):這個方法會在用戶每次訪問“目標資源(<url->pattern>index.jsp</url-pattern>)”時執行,如果需要“放行”,那么需要調用FilterChain的doFilter(ServletRequest,ServletResponse)方法,如果不調用FilterChain的doFilter()方法,那么目標資源將無法執行;

?

  destroy():服務器會在創建Filter對象之后,把Filter放到緩存中一直使用,通常不會銷毀它。一般會在服務器關閉時銷毀Filter對象,在銷毀Filter對象之前,服務器會調用Filter對象的destory()方法。

?

?

?

FilterConfig

你已經看到了吧,Filter接口中的init()方法的參數類型為FilterConfig類型。它的功能與ServletConfig相似,與web.xml文件中的配置信息對應。下面是FilterConfig的功能介紹:

  ?ServletContext getServletContext():獲取ServletContext的方法;

  String getFilterName():獲取Filter的配置名稱;與<filter-name>元素對應;

   String getInitParameter(String name):獲取Filter的初始化配置,與<init-param>元素對應;

  ?Enumeration getInitParameterNames():獲取所有初始化參數的名稱。

?

FilterChain

doFilter()方法的參數中有一個類型為FilterChain的參數,它只有一個方法:doFilter(ServletRequest,ServletResponse)。

前面我們說doFilter()方法的放行,讓請求流訪問目標資源!但這么說不嚴密,其實調用該方法的意思是,“我(當前Filter)”放行了,但不代表其他人(其他過濾器)也放行。

也就是說,一個目標資源上,可能部署了多個過濾器,就好比在你去北京的路上有多個打劫的匪人(過濾器),而其中第一伙匪人放行了,但不代表第二伙匪人也放行了,所以調用FilterChain類的doFilter()方法表示的是執行下一個過濾器的doFilter()方法,或者是執行目標資源!

如果當前過濾器是最后一個過濾器,那么調用chain.doFilter()方法表示執行目標資源,而不是最后一個過濾器,那么chain.doFilter()表示執行下一個過濾器的doFilter()方法。

?

多個過濾器執行順序

一個目標資源可以指定多個過濾器,過濾器的執行順序是在web.xml文件中的部署順序:

?

  <filter><filter-name>myFilter1</filter-name><filter-class>cn.itcast.filter.MyFilter1</filter-class></filter><filter-mapping><filter-name>myFilter1</filter-name><url-pattern>/index.jsp</url-pattern></filter-mapping><filter><filter-name>myFilter2</filter-name><filter-class>cn.itcast.filter.MyFilter2</filter-class></filter><filter-mapping><filter-name>myFilter2</filter-name><url-pattern>/index.jsp</url-pattern></filter-mapping>
public class MyFilter1 extends HttpFilter {public void doFilter(HttpServletRequest request, HttpServletResponse response,FilterChain chain) throws IOException, ServletException {System.out.println("filter1 start...");chain.doFilter(request, response);//放行,執行MyFilter2的doFilter()方法System.out.println("filter1 end...");}
}
public class MyFilter2 extends HttpFilter {public void doFilter(HttpServletRequest request, HttpServletResponse response,FilterChain chain) throws IOException, ServletException {System.out.println("filter2 start...");chain.doFilter(request, response);//放行,執行目標資源System.out.println("filter2 end...");}
}
<body>This is my JSP page. <br><h1>index.jsp</h1><%System.out.println("index.jsp"); %></body>

?

?

輸出結果

filter1 start...

filter2 start...

index.jsp

?

四種攔截方式

?

分別是:REQUEST、FORWARD、INCLUDE、ERROR。

?

  ?REQUEST:直接訪問目標資源時執行過濾器。包括:在地址欄中直接訪問、表單提交、超鏈接、重定向,只要在地址欄中可以看到目標資源的路徑,就是REQUEST;

?

  FORWARD:轉發訪問執行過濾器。包括RequestDispatcher#forward()方法、<jsp:forward>標簽都是轉發訪問;

?

  INCLUDE:包含訪問執行過濾器。包括RequestDispatcher#include()方法、<jsp:include>標簽都是包含訪問;

?

  ERROR:當目標資源在web.xml中配置為<error-page>中時,并且真的出現了異常,轉發到目標資源時,會執行過濾器。

?

可以在<filter-mapping>中添加0~n個<dispatcher>子元素,來說明當前訪問的攔截方式。

    <filter-mapping><filter-name>myfilter</filter-name><url-pattern>/b.jsp</url-pattern><dispatcher>REQUEST</dispatcher><dispatcher>FORWARD</dispatcher></filter-mapping><filter-mapping><filter-name>myfilter</filter-name><url-pattern>/b.jsp</url-pattern></filter-mapping><filter-mapping><filter-name>myfilter</filter-name><url-pattern>/b.jsp</url-pattern><dispatcher>FORWARD</dispatcher></filter-mapping>
過濾器的應用場景

過濾器的應用場景:

  執行目標資源之前做預處理工作,例如設置編碼,這種試通常都會放行,只是在目標資源執行之前做一些準備工作;[c1]?

  通過條件判斷是否放行,例如校驗當前用戶是否已經登錄,或者用戶IP是否已經被禁用;

  ?在目標資源執行后,做一些后續的特殊處理工作,例如把目標資源輸出的數據進行處理[c2]?;


?[c1]幾乎是的Sevlet中都需要寫request.setCharacterEndoing() 可以把它入到一個Filter中

?[c2]回程攔截!

?

?

設置目標資源

web.xml文件中部署Filter時,可以通過“*”來執行目標資源:

<filter-mapping><filter-name>myfilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>

?

這一特性與Servlet完全相同!通過這一特性,我們可以在用戶訪問敏感資源時,執行過濾器,例如:<url-pattern>/admin/*<url-pattern>,可以把所有管理員才能訪問的資源放到/admin路徑下,這時可以通過過濾器來校驗用戶身份。

還可以為<filter-mapping>指定目標資源為某個Servlet,例如:

<servlet><servlet-name>myservlet</servlet-name><servlet-class>cn.itcast.servlet.MyServlet</servlet-class></servlet><servlet-mapping><servlet-name>myservlet</servlet-name><url-pattern>/abc</url-pattern></servlet-mapping><filter><filter-name>myfilter</filter-name><filter-class>cn.itcast.filter.MyFilter</filter-class></filter><filter-mapping><filter-name>myfilter</filter-name><servlet-name>myservlet</servlet-name></filter-mapping>

 當用戶訪問http://localhost:8080/filtertest/abc時,會執行名字為myservlet的Servlet,這時會執行過濾器。

?

Filter小結

Filter的三個方法:

  void init(FilterConfig):在Tomcat啟動時被調用;

  void destroy():在Tomcat關閉時被調用;

  void doFilter(ServletRequest,ServletResponse,FilterChain):每次有請求時都調用該方法;

?

FilterConfig類:與ServletConfig相似,用來獲取Filter的初始化參數

  ServletContext getServletContext():獲取ServletContext的方法;

  String getFilterName():獲取Filter的配置名稱;

  String getInitParameter(String name):獲取Filter的初始化配置,與<init-param>元素對應;

  Enumeration getInitParameterNames():獲取所有初始化參數的名稱。

?

FilterChain類:

  void doFilter(ServletRequest,ServletResponse):放行!表示執行下一個過濾器,或者執行目標資源。可以在調用FilterChain的doFilter()方法的前后添加語句,在FilterChain的doFilter()方法之前的語句會在目標資源執行之前執行,在FilterChain的doFilter()方法之后的語句會在目標資源執行之后執行。

?

四個攔截方式:REQUEST、FORWARD、INCLUDE、ERROR,默認是REQUEST方式。

  REQUEST:攔截直接請求方式;

  ?FORWARD:攔截請求轉發方式;

  ?INCLUDE:攔截請求包含方式;

  ERROR:攔截錯誤轉發方式。

?

?

轉載于:https://www.cnblogs.com/flei/p/7269913.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/280978.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/280978.shtml
英文地址,請注明出處:http://en.pswp.cn/news/280978.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

03-1.JavaScript基礎語法略寫/模版字符串

基礎語法 參考前端基礎之JavaScript - Q1mi - 博客園 略寫原因 由于后續主要用jQuery編寫&#xff0c;jQuery簡化編程。大概了解JavaScript語法即可。 jQuery是一個輕量級的、兼容多瀏覽器的JavaScript庫。jQuery使用戶能夠更方便地處理HTML Document、Events、實現動畫效果…

發布適用于 .NET 7 的 .NET MAUI

點擊上方藍字關注我們&#xff08;本文閱讀時間&#xff1a;6分鐘)我們在六個月前向您介紹了 .NET 多平臺應用程序 UI (MAUI)&#xff0c;現在我們很高興地宣布 .NET MAUI 在我們的下一個主要版本 .NET 7 中普遍可用。在此短的時間范圍內&#xff0c;我們在 .NET MAUI 中的主要…

bzoj3160(FFT+回文自動機)

題目描述 https://www.lydsy.com/JudgeOnline/problem.php?id3160 題解 先把問題轉化一下&#xff0c;我們要求的是非連續對稱回文子序列。 ans回文子序列數-回文子串數。 回文子串數可以用PAM或manachar求出來。 復習了一下PAM&#xff0c;用它求回文子串數和SAM一樣&#xf…

03:數據結構 棧、隊列、鏈表與數組

算法其他篇 目錄&#xff1a; 1.1 數據結構中的一些概念1.2 棧&#xff08;stack&#xff09;1.3 隊列1.4 鏈表1.5 python中字典對象實現原理1.6 數組1.1 數據結構中的一些概念 返回頂部 1、數據結構是什么 1、簡單來說&#xff0c;數據結果就是設計數據以何種方式存儲在計…

力登:以智能化管理提升數據中心服務能力成熟度

2017年2月28日&#xff0c;由全國信息技術標準化技術委員會信息技術服務分技術委員會指導的《信息技術服務數據中心服務能力成熟度模型》發布&#xff0c;在業界首次提出“數據中心服務能力成熟度”概念&#xff0c;使得數據中心的管理真正實現了數字化和持續優化&#xff0c;是…

基于.NET 7 的 WebTransport 實現雙向通信

Web Transport 簡介WebTransport 是一個新的 Web API&#xff0c;使用 HTTP/3 協議來支持雙向傳輸。它用于 Web 客戶端和 HTTP/3 服務器之間的雙向通信。它支持通過 不可靠的 Datagrams API 發送數據&#xff0c;也支持可靠的 Stream API 發送數據。因為 HTTP/3 使用了基于 UDP…

Django01: 安裝/基礎命令/設置筆記

安裝 按官網版本支持&#xff0c;現在比較適合使用1.11版本。 下載安裝命令 pip3 install django1.11.9 新建項目 django-admin startproject mysite 運行項目 python manage.py runserver 127.0.0.1:8000 運行相關 目錄介紹 mysite/ ├── manage.py # 管理文件 └…

JavaScript校驗網址

gistfile1.txt var linkUrl https://www.baidu.com if( typeof (linkUrl) ! undefined &amp;&amp; linkUrl ! ){var strRegex ^((https|http|ftp|rtsp|mms)?://) ?(([0-9a-z_!~*\().&amp;$%-]: )?[0-9a-z_!~*\().&amp;$%-])? //ftp的user (([0-9]{1,3}.)…

線上問題隨筆記錄數據庫連接池問題

修改方法 轉載于:https://www.cnblogs.com/lvgg/p/8581506.html

數據底座_體驗當今計算機的未來:通過智能底座將您的Galaxy S4變成PC

數據底座Have you ever thought that Smartphones these days are so advanced they could actually replace the PC in your everyday computing life? Today, we here at HTG will review using the Galaxy S4 with the “Smart Dock Multimedia Hub” as a PC replacement.…

如何實現 WPF 代碼查看器控件

如何實現 WPF 代碼查看器控件CodeViewer作者&#xff1a;WPFDevelopersOrg - 驚鏵原文鏈接[1]&#xff1a;https://github.com/WPFDevelopersOrg/WPFDevelopers框架使用.NET40&#xff1b;Visual Studio 2019;代碼展示需要使用到AvalonEdit是基于WPF的代碼顯示控件&#xff0c;…

談大數據也談人工智能 郭為告訴你一個不一樣的神州控股

毋庸置疑&#xff0c;我們深處一個數據無處不在的時代&#xff0c;也就是大數據時代。作為中國智慧城市領導者的神州數碼控股有限公司&#xff08;以下簡稱“神州控股”&#xff09;近年來也在積極布局大數據&#xff0c;不過在神州控股董事局主席郭為看來&#xff0c;神州控股…

Django02: pycharm上配置django

1.setting導入 File-->Setting-->Project-->Project Interface 2.new project 新窗口 圖片畫錯 3.調試 點擊右上角調試

vue-cli中配置sass

https://www.cnblogs.com/rainheader/p/6505366.html轉載于:https://www.cnblogs.com/aidixie/p/10213997.html

php 常用函數

用到就記下來&#xff0c;持續更新......... __call(string $func_name, array args){}public方法不存在 調用此函數 通過pg_系列函數與Postgres 數據庫交互 note: php 取得對象的某一共有屬性&#xff0c;若不存在則 查看是否有get方法(魔術方法) 若有則取get方法的返回值&am…

dropbox_來自提示框:望遠鏡激光瞄準器,Dropbox桌面和Kindle剪輯轉換

dropboxOnce a week we round up some great reader tips and share them with everyone; this week we’re looking at telescope laser sights, syncing your desktop with Dropbox, and converting your Kindle Clippings file. 每周一次&#xff0c;我們收集一些很棒的讀者…

在 EF Core 7 中實現強類型 ID

本文主要介紹 DDD 中的強類型 ID 的概念&#xff0c;及其在 EF 7 中的實現&#xff0c;以及使用 LessCode.EFCore.StronglyTypedId 這種更簡易的上手方式。背景在楊中科老師 B 站的.Net Core 視頻教程[1]其中 DDD 部分講到了強類型 ID&#xff08;Strongly-typed-id&#xff09…

如何快速打造一款高清又極速的短視頻APP?

2019獨角獸企業重金招聘Python工程師標準>>> 整個短視頻的市場規模一直在增長&#xff0c;網絡數據顯示2018年已經突破100億大關&#xff0c;在2019年預測將超過200億。縱觀行業&#xff0c;在生活資訊、美食、搞笑、游戲、美妝等領域&#xff0c;短視頻流量巨大但競…

Django03: django加入APP

使用命令在已有project創建 1.創建 在manage.py同級運行命令 python manage.py startapp app01 2.django中加入app 在settings.py里的INSTALLED_APPS加入app01.apps.App01Config, INSTALLED_APPS [django.contrib.admin,django.contrib.auth,django.contrib.contenttype…

[面經]春季跳槽面筋總結 [2018年3月17]

春季跳槽面筋總結 人人都說金三銀四&#xff0c;由于一些個人的原因&#xff0c;博主也在今年的三月份抽空面了幾家公司&#xff0c;這里來總結下學習到的東西。 先簡單的說下博主的情況&#xff1a; 2015年7月份畢業&#xff0c;到現在加上實習可以算三年工作經驗base武漢&…