Java Web進階——Filter過濾器

來源:互聯網
上載者:User

標籤:

本人部落格:http://wxmimperio.coding.io/

本人郵箱:[email protected]

 

一、過濾器的介紹:
  • 在Servlet規範2.3中定義了過濾器,它是一個伺服器端的組件,可以截取使用者端的請求與響應資訊,並且對這些資訊進行過濾。
  • Servlet過濾器本身並不產生請求和響應對象,只是提供過濾功能。
  • Servlet過濾器能夠在Servlet被調用之前檢查Request對象,並修改Request Header和Request內容。
  • Servlet過濾器可以過濾的Web組件包括Servlet,JSP和HTML等檔案。

本文源碼——GitHub:

 https://github.com/imperio-wxm/wordpressCode/tree/master/Filter

二、過濾器在實際開發中的應用情境1.對使用者請求進行統一認證2.編碼轉換3.對使用者發送的資料進行過濾替換4.轉換映像格式5.對相應的內容進行壓縮三、過濾器的工作原理

【沒有過濾器】:

使用者直接存取WEB資源。

【有過濾器】:

WEB容器啟動時進行過濾器的載入,使用者發出請求到過濾器,過濾器判斷請求是否符合規則,符合規則的請求通過過濾器發送給WEB資源,WEB資源響應的資訊返回給過濾器,過濾器再將WEB資源的響應返回給使用者。

四、過濾器的生命週期(類似Servlet的生命週期)

1.執行個體化——通過web.xml進行配置載入,在容器啟動時只會執行個體化一次
2.初始化——調用init()方法,載入資訊只會執行一次
3.過濾——使用doFilter()方法進行多次過濾
4.銷毀——WEB容器關閉時調用destroy()方法進行銷毀

所有的Servlet過濾器都必須實現javax.servlet.Filter介面,並實現該介面中的三個方法。

【init()方法】
  • 這是過濾器的初始化方法,web容器建立過濾器執行個體後將調用這個方法。這個方法中可以web.xml檔案中過濾器的參數。
【doFilter()方法】
  • 這個方法完成實際的過濾操作。這個地方是過濾器的核心方法,當使用者請求訪問與過濾器關聯的URL時,web容器將先調用過濾器的doFilter方法。
  • FilterChain方法參數可以調用chain.doFilter方法,將請求傳給下一個過濾器(或目標資源),或利用轉寄、重新導向請求轉寄到其他資源。
【destroy()方法】
  • web容器在銷毀過濾器執行個體前調用該方法,在這個方法中可以釋放過濾器佔用的資源。

【生命週期代碼示範】

 

package com.filter;import javax.servlet.*;import java.io.IOException;/** * Created by wxm-Imperio */public class FirstFilter implements Filter {   @Override   public void destroy() {      System.out.println("destroy,firstFilter");   }   @Override   public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 
      throws IOException, ServletException { System.out.println("start,doFilter,firstFilter"); filterChain.doFilter(servletRequest, servletResponse); System.out.println("End,doFilter,firstFilter"); } @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("init。firstFilter"); }}

【web.xml配置】

<filter>     <filter-name>Filter的名字</filter-name>     <filter-class>Filter類的名字</filter-class>     <init-param>     <description>描述資訊可以省略或者放在此處</description>     <param-name>參數名稱</param-name>     <param-value>參數的值</param-value>     </init-param></filter><filter-mapping>     <filter-name>Filter的名字</filter-name>     <url-pattern>URL</url-pattern>     <dispatcher></dispatcher>//過濾器類型</filter-mapping>

注意:一般Filter配置在所有的Servlet之前。

五、支援多個過濾器
  • 每個過濾器有不同的URL地址
  • 當不同的過濾器URL地址相同時,會產生過濾器鏈:
  • 使用者請求——依次每個過濾器——web資源(順序是:伺服器按照web.xml中過濾器定義的先後順序組成一條鏈)
【使用者請求】——>【過濾器1Chain.doFilter前代碼——>過濾器1Chain.doFilter——>過濾器2Chain.doFilter前代碼——>過濾器1Chain.doFilter.......】——>【Servlet的Service方法處理請求】——>...........【過濾器2Chain.doFilter後代碼——>過濾器1Chain.doFilter後代碼】——>【返回使用者請求】

【過濾器鏈的web.xml配置】

<!--過濾器1的配置資訊--!><filter>     <filter-name>Filter1的名字</filter-name>     <filter-class>Filter1類的名字</filter-class>     <init-param>     <description>描述資訊可以省略或者放在此處</description>     <param-name>參數名稱</param-name>     <param-value>參數的值</param-value>     </init-param></filter><filter-mapping>     <filter-name>Filter1的名字</filter-name>     <url-pattern>URL</url-pattern>     <dispatcher></dispatcher>//過濾器類型</filter-mapping><!--過濾器2的配置資訊--!><filter>     <filter-name>Filter2的名字</filter-name>     <filter-class>Filter2類的名字</filter-class>     <init-param>     <description>描述資訊可以省略或者放在此處</description>     <param-name>參數名稱</param-name>     <param-value>參數的值</param-value>     </init-param></filter><filter-mapping>     <filter-name>Filter2的名字</filter-name>     <url-pattern>URL</url-pattern>     <dispatcher></dispatcher>//過濾器類型</filter-mapping>

注意:過濾器的執行順序就是在web.xml裡配置的順序。

六、過濾器的分類

Servlet2.5:

1.REQUEST(預設)使用者直接存取頁面時,web容器將會調用過濾器。2.FORWORD 目標源是通過RequestDispatcher的forword方法訪問時,該過濾器被調用。3.INCLUDE 目標資源時通過RequestDispatcher的include方法調用時,過濾器被調用。4.ERROR 目標資源是通過聲明式異常處理機制調用時,過濾器將被調用。 【文法】
@WebFilter(servletNames = {"SimpleServlet"} filterName = "SimpleFilter")public class LessThanSixFilter implements Filter {//類中內容}

【ERROR的配置資訊】

<error-page>   <error-code>404</error-code>   <location>/error.jsp</location></error-page><filter>   <filter-name>errorFilter</filter-name>   <filter-class>com.filter.ErrorFilter</filter-class></filter><filter-mapping>   <filter-name>errorFilter</filter-name>   <url-pattern>/error.jsp</url-pattern></filter-mapping>

【ErrorFilter過濾器代碼】

public class ErrorFilter implements Filter {   @Override   public void destroy() {   }   @Override   public void init(FilterConfig filterConfig) throws ServletException {   }   @Override   public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 
    throws IOException, ServletException { System.out.println("檢測到有錯誤資訊"); }}

 

Servlet3.0:

(新增)ASYNC 支援非同步處理
  • @WebFilter(引言)用於將一個聲明為過濾器,該註解將會在部署時被容器處理,容器將根據具體的屬性配置相應的類部署為過濾器

【非同步作業處理代碼:過濾器不等待線程,直接執行後面內容,實現非同步處理】

AsynServlet

//設定Servlet支援非同步@WebServlet(name = "AsynServlet", asyncSupported = true)public class AsynServlet extends HttpServlet {    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException { System.out.println("Servlet執行開始時間" + new Date()); //實現非同步作業 AsyncContext context = request.startAsync(); //開啟非同步線程 new Thread(new Executor(context)).start(); System.out.println("Servlet執行結束時間" + new Date()); } protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException { doPost(request, response); } //內部類類比線程 public class Executor implements Runnable { private AsyncContext context; //實現構造方法 public Executor(AsyncContext context) { this.context = context; } @Override public void run() { //執行相關的複雜業務 try { Thread.sleep(1000 * 10); //context.getRequest(); //context.getResponse(); System.out.println("業務執行完成時間" + new Date()); } catch (InterruptedException e) { e.printStackTrace(); } } }}

 

AsvnFilter過濾器

//註解@WebFilter(filterName = 
  "AsynFilter", value = {"/AsynServlet"}, asyncSupported = true, dispatcherTypes = {DispatcherType.REQUEST,DispatcherType.ASYNC})public class AsynFilter implements Filter { @Override public void destroy() { } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
     throws IOException, ServletException { System.out.println("Start..........AsynFilter"); filterChain.doFilter(servletRequest, servletResponse); System.out.println("End..........AsynFilter"); }}

web.xml配置

<servlet>   <servlet-name>AsynServlet</servlet-name>   <servlet-class>com.servlet.AsynServlet</servlet-class></servlet><servlet-mapping>   <servlet-name>AsynServlet</servlet-name>   <url-pattern>/AsynServlet</url-pattern></servlet-mapping>
七、FilterConfig的使用

Filter的init方法中提供了一個FilterConfig對象,提供相關的操作:

如擷取Filter中配置的初始化參數web.xml配置:

<filter>      <filter-name>LoginFilter</filter-name>      <filter-class>com.itzhai.login.LoginFilter</filter-class>      <init-param>          <param-name>username</param-name>          <param-value>arthinking</param-value>      </init-param></filter>

在init()方法中擷取:

@Overridepublic void init(FilterConfig filterConfig) throws ServletException {    //擷取Filter初始化參數    String username = filterConfig.getInitParameter("username");}

在Filter中訪問application:

ServletContext context = filterConfig.getServletContext();

也可以在doFilter方法中根據轉換好的request擷取:

HttpServletRequest req = (HttpServletRequest)request;ServletContext context = req.getSession().getServletContext();
八、項目執行個體

慕課網中使用者登入的加強版Demo,利用過濾器對用於請求和伺服器回應進行過濾。

GitHub源碼:https://github.com/imperio-wxm/projectDemo

參考:JSP應用開發詳解(第三版)、慕課網

Java Web進階——Filter過濾器

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.