1. 程式人生 > >Filter與Servlet的區別與聯絡

Filter與Servlet的區別與聯絡

    在我們寫程式碼時,在web.xml中總能發現類似下面的程式碼:

<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"><?xml version="1.0" encoding="UTF-8"?>   
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee    
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">   
    <welcome-file-list>   
        <welcome-file>index.jsp</welcome-file>   
    </welcome-file-list>   
    <filter>   
        <filter-name>firstFilter</filter-name>   
        <filter-class>com.test.filter.FirstFilter</filter-class>   
    </filter>   
    <filter>   
        <filter-name>secondFilter</filter-name>   
        <filter-class>com.test.filter.SecondFilter</filter-class>   
    </filter>   
    <filter-mapping>   
        <filter-name>secondFilter</filter-name>   
        <url-pattern>/*</url-pattern>   
    </filter-mapping>   
    <filter-mapping>   
        <filter-name>firstFilter</filter-name>   
        <url-pattern>/*</url-pattern>   
    </filter-mapping>   
  
    <servlet>   
        <servlet-name>firstServlet</servlet-name>   
        <servlet-class>com.alimama.servlet.FirstServlet</servlet-class>   
    </servlet>   
    <servlet-mapping>   
        <servlet-name>firstServlet</servlet-name>   
        <url-pattern>/firstServlet</url-pattern>   
    </servlet-mapping>   
</web-app>
</span></span>

    這個web.xml就涉及到了filter與servlet,那麼他們兩個有什麼區別與聯絡呢?

1. Filter
    實現javax.servlet.Filter介面,在web.xml中配置與標籤指定使用哪個Filter實現類過濾哪些URL連結。只在web啟動時進行初始化操作。

    filter 流程是線性的, url傳來之後,檢查之後,可保持原來的流程繼續向下執行,被下一個filter, servlet接收等,而servlet 處理之後,不會繼續向下傳遞。filter功能可用來保持流程繼續按照原來的方式進行下去,或者主導流程,而servlet的功能主要用來主導流程。

    在filter介面要實現三個方法:init(),destroy(),dofilter();分別是初始化,析構,和過濾,其中大部分時間花費在doFilter()方法上

    特點:可以在響應之前修改Request和Response的頭部,只能轉發請求,不能直接發出響應。filter可用來進行字元編碼的過濾,檢測使用者是否登陸的過濾,禁止頁面快取等   

    1).filter的init方法在容器初始化時載入。第一次載入容器執行順序隨機,以後再次載入順序以第一次載入順序為準。

    2).filter的doFilter方法在請求url時執行,如果有多個filter匹配,則按照<filter-mapping>順序執行(前提是doFilter方法裡面最後要呼叫FilterChain的doFilter方法,這個方法作用是繼續執行下個filter,如果沒有加,則不執行下面的filter)


2. Servlet
    servlet 流程是短的,url傳來之後,就對其進行處理,之後返回或轉向到某一自己指定的頁面。它主要用來在業務處理之前進行控制。

    servlet繼承與servlet介面,實現方法:init(),service(),destroy(),getServletConfig(),getServletInfo()方法。在呼叫時service方法時會根據請求方式呼叫doget()或者dopost()方法;

    serlvet的init方法

    1).如果web.xml中配置了<load-on-startup>屬性,則在Tomcat初始化時按其值從小到大的順序載入所有servlet的init方法。

    2).如果沒有配置<load-on-startup>屬性,容器初始化時不載入。在請求匹配的url時進行載入,並且只加載最後一個servlet的init方法。其他的servlet不載入。

    3).servlet的doGet、doPost方法:在請求匹配的url路徑時載入,而且只加載最後一個servlet的方法,其他方法不載入。

    filter和servlet同時存在,且容器初始化都要載入,則先載入filter再載入servlet的init方法。

    如果請求的url既匹配filter又匹配servlet,並且servlet的init方法沒有在容器初始化載入,則先載入匹配的servlet的最後一個servlet的init方法,再按順序執行filter方法,最後再執行匹配的最後一個servlet方法

     在網上看到一張圖與大家分享:

Filter

Servlet

介面

實現Filter介面

實現Servlet介面

使用步驟

1、建立類,繼承介面

2、實現方法

init()

doFilter()

destroy()

3、配置WEB-INF/web.xml

1、建立類,繼承介面

2、實現方法

init()

service()

destroy()

getServletConfig()

getServletInfo()

3、配置WEB-INF/web.xml

初始化時間

Servlet容器啟動之後即初始化

Servlet類被呼叫之後初始化、先於Filter呼叫。

初始化可以在容器啟動後被呼叫但需要配置。

呼叫順序

1. 按照web.xml中的對映配置順序按照配置條件從後向前呼叫

2. 層次呼叫doFilter()方法中FilterChain.doFilter()之前的內容

3. 呼叫Servlet中的service()方法

4. service方法執行完畢後,層次呼叫doFilter()中FilterChain.doFilter()之後的方法,順序與之前的相反

按照web.xml中的對映配置順序按照配置條件從後向前呼叫第一個滿足條件的Servlet,呼叫之前事先執行滿足條件的Filter,不存在層次呼叫Servlet問題

銷燬

伺服器停止後銷燬,晚於Servlet銷燬之後

伺服器停止後銷燬

作用

1. 在HttpServletRequest到達Servlet之前,攔截客戶的HttpServletRequest。

2. 根據需要檢查HttpServletRequest,也可以修改HttpServletRequest頭和資料。

3. 在HttpServletResponse到達客戶端之前,攔截HttpServletResponse。

4. 根據需要檢查HttpServletResponse,也可以修改HttpServletResponse頭和資料。

主要是處理客戶端的請求並將其結果傳送到客戶端。

    filter的初始化是在servlet容器啟動時,而Servlet類被呼叫之後初始化、先於Filter呼叫。初始化可以在容器啟動後被呼叫但需要配置。(filter的初始化根據在web.xml中filter的宣告順序,注意filtermapping必須放在filter宣告之後使用。servlet被呼叫初始化,先於filter呼叫,是指chain.fiter(),service(),chainfiter()之後的程式碼)

    呼叫順序:filter的呼叫順序:

    1. 按照web.xml中的對映配置順序按照配置條件從後向前呼叫

    2. 層次呼叫doFilter()方法中FilterChain.doFilter()之前的內容(filter-mapping的name先呼叫doFilter方法,但是每個dofilter方法的內部存在chain.dofilter會呼叫下一個filter-mapping,一直到不存在下一個filter後在返回,執行chain.dofilter()後面的程式碼)(相當於遞迴呼叫)

    3. 呼叫Servlet中的service()方法

    4. service方法執行完畢後,層次呼叫doFilter()中FilterChain.doFilter()之後的方法,順序與之前的相反

    servlet的呼叫順序:

    按照web.xml中的對映配置順序按照配置條件從後向前呼叫第一個滿足條件的Servlet,呼叫之前事先執行滿足條件的Filter,不存在層次呼叫Servlet問題

    當然咱們通俗易懂的來講,filter就是用來攔截進行一些日誌類似aop的功能,而servlet就是轉發到別的頁面。filter我們可以不配置也就不用,但是目前所有程式碼基本上都配置了servlet。