天天看點

servlet/filter/listener/interceptor差別與聯系(轉)

一、概念:

         1、servlet:servlet是一種運作伺服器端的java應用程式,具有獨立于平台和協定的特性,并且可以動态的生成web頁面,它工作在用戶端請求與伺服器響應的中間層。

         2、filter:filter是一個可以複用的代碼片段,可以用來轉換HTTP請求、響應和頭資訊。Filter不像Servlet,它不能産生一個請求或者響應,它隻是修改對某一資源的請求,或者修改從某一的響應。

        3、listener:監聽器,從字面上可以看出listener主要用來監聽隻用。通過listener可以監聽web伺服器中某一個執行動作,并根據其要求作出相應的響應。通俗的語言說就是在application,session,request三個對象建立消亡或者往其中添加修改删除屬性時自動執行代碼的功能元件。

         4、interceptor:是在面向切面程式設計的,就是在你的service或者一個方法,前調用一個方法,或者在方法後調用一個方法,比如動态代理就是攔截器的簡單實作,在你調用方法前列印出字元串(或者做其它業務邏輯的操作),也可以在你調用方法後列印出字元串,甚至在你抛出異常的時候做業務邏輯的操作。

      5、servlet、filter、listener是配置到web.xml中,interceptor不配置到web.xml中,struts的攔截器配置到struts.xml中。spring的攔截器配置到spring.xml中。 

      二、生命周期:

        1、servlet:servlet的生命周期始于它被裝入web伺服器的記憶體時,并在web伺服器終止或重新裝入servlet時結束。servlet一旦被裝入web伺服器,一般不會從web伺服器記憶體中删除,直至web伺服器關閉或重新結束。 Servlet一般繼承HttpServlet,建立servlet,其中init方法,調用service方法,根據請求調用相應的doxx方法,最終銷毀servlet;如果加上load-on-start為1時候,Web應用啟動時候加載此Servlet;

           (1)、裝入:啟動伺服器時加載Servlet的執行個體; 

           (2)、初始化:web伺服器啟動時或web伺服器接收到請求時,或者兩者之間的某個時刻啟動。初始化工作有init()方法負責執行完成; 

           (3)、調用:從第一次到以後的多次通路,都是隻調用doGet()或doPost()方法; 

           (4)、銷毀:停止伺服器時調用destroy()方法,銷毀執行個體。 

         2、filter:(一定要實作javax.servlet包的Filter接口的三個方法init()、doFilter()、destroy(),空實作也行) 

         (1)、啟動伺服器時加載過濾器的執行個體,并調用init()方法來初始化執行個體; 

         (2)、每一次請求時都隻調用方法doFilter()進行處理; 

         (3)、停止伺服器時調用destroy()方法,銷毀執行個體。

         3、listener:類似于servlet和filter

         web.xml 的加載順序是:context- param -> listener -> filter -> servlet 

         4、interceptor:以struts的攔截器為例,加載了struts.xml以後,初始化相應攔截器。當action請求來時調用intercept方法,伺服器停止銷毀interceptor。

   三、職責

      1、servlet:

        建立并傳回一個包含基于客戶請求性質的動态内容的完整的html頁面;

        建立可嵌入到現有的html頁面中的一部分html頁面(html片段);

        讀取用戶端發來的隐藏資料;

        讀取用戶端發來的顯示資料;

        與其他伺服器資源(包括資料庫和java的應用程式)進行通信;

        通過狀态代碼和響應頭向用戶端發送隐藏資料。

      2、filter:

        filter能夠在一個請求到達servlet之前預處理使用者請求,也可以在離開servlet時處理http響應:

        在執行servlet之前,首先執行filter程式,并為之做一些預處理工作;

        根據程式需要修改請求和響應;

        在servlet被調用之後截獲servlet的執行

       3、listener:職責如概念。

         servlet2.4規範中提供了8個listener接口,可以将其分為三類,分别如下:

         第一類:與servletContext有關的listner接口。包括:ServletContextListener、ServletContextAttributeListener

         第二類:與HttpSession有關的Listner接口。包括:HttpSessionListner、HttpSessionAttributeListener、HttpSessionBindingListener、                      HttpSessionActivationListener;

         第三類:與ServletRequest有關的Listener接口,包括:ServletRequestListner、ServletRequestAttributeListener

        4、interceptor:與過濾器十分相似,通過層層攔截,處理使用者的請求和響應。

   四、幾個差別:

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

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

          Filter可認為是Servlet的一種“變種”,它主要用于對使用者請求進行預處理,也可以對HttpServletResponse進行後處理,是個典型的處理鍊。它與Servlet的差別在于:它不能直接向使用者生成響應。完整的流程是:Filter對使用者請求進行預處理,接着将請求交給Servlet進行處理并生成響應,最後Filter再對伺服器響應進行後處理。

          Filter必須實作javax.Servlet.Filter接口,并且必須定義以下三個方法:init(),destory(),doFilter().

         過濾器Filter也具有生命周期:init()->doFilter()->destroy()

          當一個servlet比對成功後就不會在往下去比對了, 。 其他還有其他的比對規則:

          (1), 精确路徑的比對;例子:比如servletA 的url-pattern為 /test,servletB的url-  pattern為 /* ,這個時候,如果我通路的url為http://localhost/test ,這個時候容器就會先 進行精确 路徑比對,發現/test正好被servletA精确比對,那麼就去調用servletA,也不會去理會其他的servlet了。

                  (2), 最長路徑的比對:例子:servletA的url-pattern為/test/*,而servletB的url-pattern為/test/a/*,此時通路http://localhost/test/a時,容器會選擇路徑最長的servlet來比對,也就是這裡的servletB。

            (3). 擴充比對,如果url最後一段包含擴充,容器将會根據擴充選擇合适的servlet。例子:servletA的url-pattern:*.action

                而對于filter ,它沒有映射的路徑,在配置檔案中不需要寫url,隻需要寫filter類就好了,不會像servlet那樣隻比對一個servlet,因為filter的集合是一個鍊,是以隻要考慮執行的順序就可以,而不會出現隻選擇一個filter,寫的每個filter都會執行。Filter的處理順序和filter-mapping在web.xml中定義的順序相同。

                  filter可用來進行字元編碼的過濾,檢測使用者是否登陸的過濾,禁止頁面緩存等

       3,servlet,filter都是針對url之類的,而listener是針對對象的操作的,如session的建立,session.setAttribute的發生,在這樣的事件發生時做一些事情。

     可用來進行:Spring整合Struts,為Struts的action注入屬性,web應用定時任務的實作,線上人數的統計等

        4,interceptor 攔截器,類似于filter,不過在struts.xml中配置,不是在web.xml,并且不是針對URL的,而是針對action,當頁面送出action時,進行過濾操作,相當于struts1.x提供的plug-in機制,可以看作,前者是struts1.x自帶的filter,而interceptor 是struts2 提供的filter.

    與filter不同點:(1)不在web.xml中配置,而是在struts.xml中完成配置,與action在一起

                    ( 2  ) 可由action自己指定用哪個interceptor 來在接收之前做事    

       5,struts2中的過濾器和攔截器的差別與聯系:

      (1)、攔截器是基于java反射機制的,而過濾器是基于函數回調的。

      (2)、過濾器依賴與servlet容器,而攔截器不依賴與servlet容器。

      (3)、攔截器隻能對Action請求起作用,而過濾器則可以對幾乎所有請求起作用。

      (4)、攔截器可以通路Action上下文、值棧裡的對象,而過濾器不能。

      (5)、在Action的生命周期中,攔截器可以多次調用,而過濾器隻能在容器初始化時被調用一次。