過濾器:基本功能就是對Servlet的調用過程進行攔截,從而在Servlet處理請求和響應的時候增加一些特定的功能。
常見的Filter 實現的功能有,URL級別的權限訪問控制、過濾敏感詞彙、壓縮響應星系、設置POST方式得同意編碼。
程序中的過濾器理解角度可以比喻爲生活中得自來水。可以將水腫得雜誌。有害物質等進行過濾。
當客戶端向服務器中的資源發出請求時,會先被過濾器Filter進行攔截處理,之後再將處理後的請求轉發給真正的服務器資源,此外服務器接受到的請求並給出響應,響應會先回被過濾器攔截處理,之後再將處理後的響應轉發給客戶端,及在請求和響應的過程前,都會被過濾器進行攔截處理。
- 而在程序中的過濾器,實際就是實現了javax.servlet.Filter 接口的類,javax.servlet.Filter接口中定義了以下3個方法:
- void init(FilterConfig conf): 執行過濾初始化,Web容器會在web項目啓動的時候,自動調用該方法。
- void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 當請求和響應攔截後,就通過doFilter方法來處理,request參數就是攔截得請求對象,可以使用FilterChain參數的doFilter方法講攔截得請求和響應釋放。
- void destroy() 用於釋放或關閉Filter 對象打開的資源,如數據庫、關閉IO流等操作,在Web項目關閉時候,由Web容器自動調用該方法。
Filter 得init()和destroy()方法鴿子只會被調用一次,而doFilter方法會在每次客戶發出請求時候被調用。
init方法裏的FilterConfig參數,主要爲過濾器提供初始化參數。
FilterConfig是一個接口,常使用的方法如下:
- String getFilterName() 獲取web.xml 中過濾器得名稱
- String getInitParameter(String param):獲取web.xml 中參數名對應的參數值
- ServletContext getServletContext(): 獲取web.xml應用程序的ServletContext
第一個Filter程序
創建Servlet
public class MyServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("doGet…");
}
…
}
在web.xml中配置此Servlet
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>
MyServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/MyServlet</url-pattern>
</servlet-mapping>
<filter>
<filter-name>MyFirstFilter</filter-name>
<filter-class>
MyFirstFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFirstFilter</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
上面既配置了Servlet,也配置累當訪問這個Servlet 得Filter,在訪問這個Servlet之前,請求會被這個Filter攔截下。
Filter類
public class MyFirstFilter implements Filter{
@Override
public void init(FilterConfig arg0) throws ServletException{
System.out.println("過濾器01的初始化init()方法...");
}
@Override
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException{
System.out.println("過濾器01的執行方法:doFilter()方法...");
}
@Override
public void destroy(){
System.out.println("過濾器01的銷燬destory()方法...");
System.out.println("攔截請求01...");
chain.doFilter(request, response);
System.out.println("攔截響應01...");
}
}
Filter中的配置方法和Servlet中的配置方法類似,先通過<url-pattern> 匹配腰攔截得請求,在根據<filter-name>找到對應的過濾器中處理類<filter-class>,最後執行過濾類中的init()、doFilter()
、destroy()
等方法。
上面的方法中使用 chain.doFilter(request, response);得作用就是將攔截器處理之後將其釋放掉,交給下個Filter或者到達Servlet去處理,而在doFilter之前處理的就是攔截器請求時執行的代碼,而之後的代碼就是攔截器響應執行的代碼。
Filter 得映射
web.xml中的<url-pattern>元素來配置需要攔截得請求,如果是這樣的配置
<url-pattern>/*</url-pattern> 表示攔截項目中所有的請求。
<url-pattern>/*.do</url-pattern> 攔截所有的以.do 結尾的請求。
Filter鏈,就是爲如下所示
<filter>
<filter-name>MyFirstFilter</filter-name>
<filter-class>
MyFirstFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFirstFilter</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
<filter>
<filter-name>MySecondFilter</filter-name>
<filter-class>
MySecondFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>MySecondFilter</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
構建多個Filter,Filter 得順序是根據以上配置的順序執行的。
攔截請求:請求先被MyFirstFilter攔截,再被MySecondFilter攔截;
攔截響應:與攔截請求的順序正好相反:即響應先被MySecondFilter攔截,再被MyFirstFilter攔截
監聽器
在Web應用程序的運行期間,Web容器會創建和銷燬四個對象:ServletContext
、HttpSession
、ServletRequest
、PageContext
,這些對象被稱爲“域對象”(除了PageContext
以外,Servlet API爲其他三個域對象都提供了各自的監聽器,用來監聽它們的行爲。
ervlet API提供了ServletContextListener
、HttpSessionListener
、ServletRequestListener
三個監聽器接口,用來分別監聽ServletContext
、HttpSession
、ServletRequest
三個域對象。當這三個域對象創建或銷燬時,就會自動觸發相應的監聽器接口。
ServletContextListener
接口可以用來監聽ServletContext
域對象的創建、銷燬過程。當在Web應用程序中註冊了一個或多個實現了ServletContextListener
接口的事件監聽器時,Web容器就會在創建、銷燬每個ServletContext
對象時都產生一個相應的事件對象,然後依次調用每個ServletContext
事件監聽器中的處理方法,並將產生的事件對象傳遞給這些方法來完成事件的處理工作。