中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

filter過濾器怎么在Java項目中使用

發布時間:2020-11-27 16:20:40 來源:億速云 閱讀:338 作者:Leah 欄目:編程語言

這篇文章將為大家詳細講解有關filter過濾器怎么在Java項目中使用,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

Filter過濾器技術。通過過濾器,可以對來自客戶端的請求進行攔截,進行預處理或者對最終響應給客戶端的數據進行處理后再輸出。

要想使用Filter過濾器,非常簡單,只要實現Servlet  API中的Filter接口即可,同時在該web應用【WEB-INF】目錄下的web.xml文件中配置<filter>和<filter-mapping>兩個標簽。其中可以根據配置指定過濾的頁面或者Servlet。

也就是說我們在web工程中光光寫Filter過濾器的Java代碼是不會起作用的,要在web.xml文件中對過濾器進行注冊和映射,在學習Filter之前我們先來學習如何注冊和映射
關于注冊:

需要在web.xml文件中配置<filter>標簽,這還不夠,<filter>標簽下的<filter-name>與<filter-class>是必須要填的內容。

<filter>標簽中有如下子元素:

  1. <description>用于描述該標簽,非必須;

  2. <filter-name>為過濾器指定一個名稱,必須的

  3. <filter-class>指定該過濾器使用的web工程中的哪一個filter類,包含包名與類名,必須的;

  4. <init-param>為過濾器的初始化提供參數,非必須,后面有例子。

關于映射:

需要在web.xml文件中配置<filter-mapping>標簽,這還不夠,<filter-mapping>標簽下的<filter-name>以及<url-pattern>或<servlet-name>之一是必須的。

<filter-mapping>標簽中有如下子元素:

  1. <filter-name>設置要映射過濾器的名稱,該名稱必須同<filter>標簽下的<filter-name>的值一致。

  2. <url-pattern>設置過濾器要攔截過濾的請求路徑,例如“/*”則表示對該web應用下所有的請求都進行攔截過濾。

  3. <servlet-name>如果只要攔截過濾訪問某個Servlet,就可以使用該標簽來替代<url-pattern>。

  4. <dispatcher>設置攔截過濾客戶端請求的方式,有REQUEST,INCLUDE,FORWARD,ERROR四種(請注意均為大寫)。非必須則默認為REQUEST,使用多個<dispatcher>標簽來設置多種請求方式。

關于<dispathcer>的四種方式,這里再簡單的介紹一下:

  1. REQUEST:當用戶直接訪問我們的資源時,這時我們設置的過濾器就會進行攔截。但如果以轉發和包含方式訪問資源,那么該過濾器則不會被調用。

  2. INCLUDE:當使用RequestDispatch的include方法請求時,該過濾器會被調用。

  3. FORWARD:當使用RequestDispatch的forward方法時請求資源時,該過濾器會被調用,尤其是在MVC設計模式下,JSP都被保護起來,必須要通過Servlet進行轉發才能訪問JSP,那么該過濾器就是在Servlet轉發到JSP這個過程中被執行。

  4. ERROR:當請求是通過錯誤異常進行跳轉時就會調用該過濾器。

一個簡單的對過濾器的注冊和映射的示例:

<filter>
  <filter-name>FilterDemo1</filter-name>
  <filter-class>com.bjpowernode.web.filter.FilterDemo1</filter-class>
 </filter>
  
 <filter-mapping>
  <filter-name>FilterDemo1</filter-name>
  <url-pattern>/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>FORWARD</dispatcher>
</filter-mapping>

在Servlet API 中關于Filter舉例了使用過濾器能用來做些什么:

filter過濾器怎么在Java項目中使用

這里我也說明下平時Filter能在哪些方面會被經常用到:

① Filter可以作用在請求資源執行之前,進行權限檢查,檢查用戶是否有權限,如有權限則放行請求;如果沒有,則拒絕訪問。

② Filter可以作用在請求資源執行之前,對Request和Response對象進行預處理操作,從而實現一些web應用的全局性設置,比如解決中文亂碼問題。

③ Filter可以作用在最終響應輸出之前,對輸出Response對象中的數據進行處理,例如將輸出的數據進行壓縮。

Filter只有3個方法:

filter過濾器怎么在Java項目中使用

其中destroy()方法和init(…)方法是生命周期方法,因為過濾器無論如何都要在請求任何資源之前進行,所以任何Web應用在部署的時候,服務器就會調用Filter過濾器的init方法進行初始化,而關于過濾器的銷毀,則是將該過濾器移除或者服務器關閉就會執行destory方法。

而我們通常要使用過濾器處理請求,則重點在于doFilter(…)方法。當請求要經過一個過濾器的時候,就會由服務器調用doFilter方法。

我們先來看看一個帶有過濾器Filter的web應用的請求和響應流程:

filter過濾器怎么在Java項目中使用

記住:從請求到響應這個流程會經過Filter對象兩次!

在doFilter這一個方法中就可以對著兩次經過的過程進行處理,那么這里就有一個問題了,如果能通過過濾器,那么就到過濾器后面了,貌似應該是執行完doFilter方法了,而服務器的響應又經過過濾器,難道又要執行doFilter方法一次?但是這個方法里面的代碼不是也有處理最開始請求的嗎?

這就跟doFilter方法中的第三個參數FilterChain有關了,FilterChain對象是過濾器鏈,這個我們稍后會介紹。在FilterChain對象中只有一個方法:

filter過濾器怎么在Java項目中使用

=也是叫doFilter方法(千萬別和Filter接口的doFilter方法弄混了)。簡單的說下這個方法,只要調用了這個方法,就會將請求交給后面一個Filter進行過濾(一個Web應用中可以有多個Filter),如果該Filter是最后一個,那么調用該方法則將執行請求,也就是到我們的應用中獲取資源。

因此從請求到響應這個流程經過Filter的兩次處理分別是在FilterChain.doFilter方法的前面和后面!如下圖所示:

filter過濾器怎么在Java項目中使用

那么下面我們就先以一個簡單的例子來熟悉下Filter吧:

例1:

創建web工程FilterLearning,創建一個FilterDemo1類,同時這個類要實現javax.servlet.Filter接口。如下代碼:

public class FilterDemo implements Filter {
 
   @Override
   public void doFilter(ServletRequest request, ServletResponse response,
       FilterChain chain) throws IOException, ServletException {
     
     System.out.println("hello filter");
   }
 
   //此處省略init方法和destory方法
 }

寫好Filter的Java代碼還沒完,還要在web應用下的web.xml文件中配置如下信息:

 <filter>
    <filter-name>FilterDemo1</filter-name>
    <filter-class>com.bjpowernode.web.filter.FilterDemo</filter-class>
  </filter>
  
  <filter-mapping>
    <filter-name>FilterDemo1</filter-name>
    <url-pattern>/*</url-pattern>
 </filter-mapping>

注意:因為我在<url-pattern>中配置為“/*”,則訪問我wen應用中任何資源都會經過該Filter過濾器。如果只想對于index.jsp主頁的請求進行過濾,可以設為<url-pattern>/index.jsp</url-pattern>。

我們在index.jsp中簡單的使用JSP腳本來演示如果有請求來就輸入一段文本到控制臺上:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 
 <!DOCTYPE HTML>
 <html>
  <head>  
   <title>index</title>
  </head>
  
  <body>
   <%
     System.out.println("Long live SD !");
   %>
  </body>
 </html>

接下來將該web應用部署到服務器中,我們就訪問index.jsp,以下是我們訪問了index.jsp后控制臺的情況:

filter過濾器怎么在Java項目中使用

首先,我們可以保證在我們訪問index.jsp后這個請求確實經過了Filter過濾器,但是我們的請求好像就只到過濾器而沒有到我們真正需要的資源index.jsp?這是因為我們沒有在Filter的doFilter方法中調用過濾器鏈FilterChain對象的doFilter方法,自然無法將請求繼續往后面傳遞。我們將在例2中修改。

例2:

我們將例1中的FilterDemo1類進行修改,使其能訪問到我們所需要的資源,很簡單,在doFilter的方法中添加過濾器鏈FilterChain對象的doFilter方法即可:

public class FilterDemo implements Filter {
 
   @Override
   public void doFilter(ServletRequest request, ServletResponse response,
       FilterChain chain) throws IOException, ServletException {
     
     System.out.println("hello filter");
     chain.doFilter(request, response);
   }
   //此處省略init方法和destory方法
 }

其他如web.xml中的配置和index.jsp中的代碼保持不變,現在我們再來訪問下該web應用中的index.jsp,并觀察控制臺:

filter過濾器怎么在Java項目中使用

可以看到我們的請求經過過濾器,執行了過濾器的一段代碼(System.out.println(“hello filter”)),然后將請求繼續執行!正是因為FilterChain.doFilter方法才使我們通過過濾器繼續向后尋找我們所需的資源。

那么還記得我們之前說過的從請求到響應會經過兩次過濾器嗎,是的在獲取了我們所需的資源后還會到過濾器一趟,而至于這時候是否將響應再做處理取決于過濾器鏈FilterChain.doFilter方法后面還是否有代碼。我們將在例3中完整的展現從請求到響應經過過濾器兩次的流程。

例3:

我們將例2中的FilterDemo1類進行修改,只要在FilterChain.doFilter方法后面添加代碼,就是第二次(即響應)經過過濾器所要執行的處理:

public class FilterDemo implements Filter {
 
   @Override
   public void doFilter(ServletRequest request, ServletResponse response,
       FilterChain chain) throws IOException, ServletException {
     
     System.out.println("hello filter");
     chain.doFilter(request, response);
     System.out.println("goodbye filter");
   }
   //此處省略init方法和destory方法
 }

其他如web.xml中的配置和index.jsp中的代碼保持不變,現在我們再來訪問下該web應用中的index.jsp,并觀察控制臺:

filter過濾器怎么在Java項目中使用

這個結果證明了從請求到響應確實經過過濾器兩次,同時也說明了在Filter的doFilter方法中“過濾——取資源——再過濾”執行的順序。

現在我們再回到Filter接口的init方法,我們可以看到在這個方法內有一個參數FilterConfig,這個是由服務器傳給我們的對象。如果我們在web.xml文件中配置了過濾器的初始化參數,就可以通過該FilterConfig對象來在代碼中獲取使用。

這個過濾器參數的初始化配置可以在<filter>標簽中配置<init-param>,并在這個<init-param>標簽下再配置<param-name>和<param-value>。

FilterConfig有如下方法:

filter過濾器怎么在Java項目中使用

當然如果我們是要獲取配置的初始化參數則只需關注getInitParameter方法或getInitParameterNames方法。

一般來說我們可以在init方法中獲取配置初始化參數并進行處理;也可以通過對象引用將FilterConfig對象在doFilter方法中處理參數,如例4所示。

例4:

在web.xml文件中配置過濾器和初始化參數:

 <filter>
    <filter-name>FilterDemo1</filter-name>
   <filter-class>com.bjpowernode.web.filter.FilterDemo1</filter-class>
    <init-param>
      <param-name>Love</param-name>
      <param-value>LRR</param-value>
    </init-param>
  </filter>
  
  <filter-mapping>
    <filter-name>FilterDemo1</filter-name>
    <url-pattern>/*</url-pattern>
 </filter-mapping>

在Java中編寫Filter接口的實現類FilterDemo1:

public class FilterDemo implements Filter {
   private FilterConfig filterConfig ;
   
   @Override
   public void doFilter(ServletRequest request, ServletResponse response,
       FilterChain chain) throws IOException, ServletException {
     
     String value = filterConfig.getInitParameter("Love");
     System.out.println(value);
   }
   
   @Override
   public void init(FilterConfig filterConfig) throws ServletException {
     this.filterConfig = filterConfig;
   }
   //此處省略destroy方法
 }

因為配置的原因,所以我們隨便訪問個資源都可以經過該過濾器,那么就訪問index.jsp好了,看看控制臺的結果:

filter過濾器怎么在Java項目中使用

正如我們在web.xml文件所配置的初始化參數一樣。

上面介紹的都是只有一個Filter過濾器的情況下,有時候我們會因為要過濾的功能不同添加多個過濾器,這就有一個順序的問題了,尤其是從取得資源后再返回到過濾器的順序。下面這張圖就能很清晰的看到我們要注意的順序了:

filter過濾器怎么在Java項目中使用

例5:

來寫兩個Filter來說明下從請求到響應過濾器的處理順序。

創建一個web工程,創建一個FilterDemo1類,同時這個類要實現javax.servlet.Filter接口。如下代碼:

public class FilterDemo1 implements Filter {
   
   public void doFilter(ServletRequest request, ServletResponse response,
       FilterChain chain) throws IOException, ServletException {
     
     System.out.println("Hello filter 1");
     chain.doFilter(request, response);
     System.out.println("Goodbye filter 1");
   }
 //此處省略init方法和destroy方法
 }

創建第二個Filter接口實現類FilterDemo2,代碼如下:

 public class FilterDemo2 implements Filter {
 
   public void doFilter(ServletRequest request, ServletResponse response,
       FilterChain chain) throws IOException, ServletException {
     System.out.println("Hello filter 2");
     chain.doFilter(request, response);
     System.out.println("Goodbye filter 2");  
   }
 //此處省略init方法和destroy方法
 }

過濾器要想能被服務器調用,還必須要在該web工程下的web.xml中配置過濾器及其映射,而這個配置的順序就是影響多個過濾器工作先后的順序:

 <filter>
    <filter-name>FilterDemo1</filter-name>
   <filter-class>com.bjpowernode.web.filter.FilterDemo1</filter-class>
 </filter>
  
  <filter-mapping>
    <filter-name>FilterDemo1</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <filter>
    <filter-name>FilterDemo2</filter-name>
    <filter-class>com.bjpowernode.web.filter.FilterDemo2</filter-class>
  </filter>
  
  <filter-mapping>
    <filter-name>FilterDemo2</filter-name>
    <url-pattern>/*</url-pattern>
 </filter-mapping>

而我們要訪問的資源文件就以index.jsp為例好了,那么我們用一段JSP腳本通過在控制臺打印來驗證過濾器工作的順序過程:

 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 
 <!DOCTYPE HTML>
 <html>
  <head>  
   <title>index</title>
  </head>
  
  <body>
   <%
     System.out.println("Long live SD !");
   %>
  </body>
 </html>

現在啟動服務器,部署該工程,通過訪問index.jsp來看看控制臺情況:

filter過濾器怎么在Java項目中使用

關于filter過濾器怎么在Java項目中使用就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

汝阳县| 天津市| 巴林右旗| 镇安县| 日照市| 桂林市| 大冶市| 潜山县| 灌南县| 房产| 涪陵区| 灵宝市| 双辽市| 固原市| 漳浦县| 积石山| 通辽市| 河源市| 屏东县| 尤溪县| 资兴市| 罗江县| 白朗县| 玉龙| 涿州市| 辽源市| 商丘市| 宁都县| 萝北县| 嘉荫县| 大兴区| 时尚| 平利县| 札达县| 吴川市| 龙海市| 富阳市| 潞城市| 镇雄县| 天台县| 高陵县|