一、概念
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中。
二、加載順序
web.xml 的加載順序是:context- param -> listener -> filter -> servlet
三、職責
1.servlet:
(1)創建並返回一個包含基於客戶請求性質的動態內容的完整的html頁面
(2)創建可嵌入到現有的html頁面中的一部分html頁面(html片段)
(3)讀取客戶端發來的隱藏數據
(4)讀取客戶端發來的顯示數據
(5)與其他服務器資源(包括數據庫和java的應用程序)進行通信
(6)通過狀態代碼和響應頭向客戶端發送隱藏數據。
2.filter:
(1)filter能夠在一個請求到達servlet之前預處理用戶請求,也可以在離開servlet時處理http響應
(2)在執行servlet之前,首先執行filter程序,並為之做一些預處理工作
(3)根據程序需要修改請求和響應
(4)在servlet被調用之後截獲servlet的執行。
3.listener:
servlet2.4規范中提供了8個 listener 接口,可以將其分為三類,分別如下:
(1)與 servletContext 有關的 listne r接口。包括:ServletContextListener、ServletContextAttributeListener
(2)與 HttpSession 有關的 Listner 接口。包括:HttpSessionListner、HttpSessionAttributeListener、HttpSessionBindingListener、 HttpSessionActivationListener
(3)與 ServletRequest 有關的 Listener 接口,包括:ServletRequestListner、ServletRequestAttributeListener
四、區別
1.servlet:servlet 流程是短的,url傳來之後,就對其進行處理,之後返回或轉向到某一自己指定的頁面。它主要用來在業務處理之前進行控制。
2.filter:流程是線程性的,url傳來之後,檢查之後,可保持原來的流程繼續向下執行,被下一個filter, servlet接收等,而 servlet 處理之後,不會繼續向下傳遞。
filter 功能可用來保持流程繼續按照原來的方式進行下去,或者主導流程,而servlet的功能主要用來主導流程。可以將 Filter 看成是 servlet 的一個補充(擦屁股的)。
Filter可認為是Servlet的一種“變種”,它主要用於對用戶請求進行預處理,也可以對HttpServletResponse進行後處理,是個典型的處理鏈。
它與Servlet的區別在於:它不能直接向用戶生成響應。
完整的流程是:Filter對用戶請求進行預處理,接著將請求交給Servlet進行處理並生成響應,最後Filter再對服務器響應進行後處理。
3.匹配規則
當一個請求發送到servlet容器的時候,容器先會將請求的url減去當前應用上下文的路徑作為servlet的映射url,比如我訪問的是http://localhost/test/aaa.html(我的應用上下文是test),
容器會將http://localhost/tes去掉,將剩下的/aaa.html部分拿來做servlet的映射匹配,也就是拿這剩下的部分與web.xml中配置的servlet的url-pattern進行匹配。
注意:這個映射匹配過程是有一定的規則的,而且每次匹配最終都只匹配一個 servlet。(這一點和filter不同)
servlet 匹配規則:當一個servlet匹配成功後就不會在往下去匹配了
精確路徑的匹配:
例子:比如servletA 的url-pattern為 /test,servletB的url- pattern為 /* ,這個時候,如果我訪問的url為http://localhost/test ,
這個時候容器就會先 進行精確 路徑匹配,發現/test正好被servletA精確匹配,那麼就去調用servletA,也不會去理會其他的servlet了。
最長路徑的匹配:
例子:servletA的url-pattern為/test/*,而servletB的url-pattern為/test/a/*,此時訪問http://localhost/test/a時,
容器會選擇路徑最長的servlet來匹配,也就是這裡的servletB。
擴展匹配:如果url最後一段包含擴展,容器將會根據擴展選擇合適的servlet。
例子:servletA的url-pattern:*.action
4.servlet,filter 都是針對 url 之類的,而 listener 是針對對象的操作的,如 session 的創建,session.setAttribute 的發生,在這樣的事件發生時做一些事情。
可用來進行:Spring整合Struts,為Struts的action注入屬性,web應用定時任務的實現,在線人數的統計等
5.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 來在接收之前做事
6.struts2中的過濾器和攔截器的區別與聯系:
(1)攔截器是基於java反射機制的,而過濾器是基於函數回調的。
(2)過濾器依賴與servlet容器,而攔截器不依賴與servlet容器。
(3)攔截器只能對Action請求起作用,而過濾器則可以對幾乎所有請求起作用。
(4)攔截器可以訪問Action上下文、值棧裡的對象,而過濾器不能。
(5)在Action的生命周期中,攔截器可以多次調用,而過濾器只能在容器初始化時被調用一次。