過濾器就是向web應用程序的請求和和響應添加功能的組件。過濾器能夠實現客戶端和目標資源之間的交互信息進行篩選和過濾,最終保留有效的數據信息。
web容器復制創建過濾器的實例來完成過濾器的實例化,只會實例化一次。
在進行過濾工作前會調用init()方法來實現初始化操作,也只初始化一次。
調用doFilter()方法來實現過濾器的特定功能
調用destory()方法,釋放過濾器所占用的資源。
(1).創建實現Filter接口的類
(2).在doFilter()中編寫實現過濾的方法。
(3).調用下一個過濾器或者web資源
(4).在web.xml文件中配置過濾器
package demo.web.servlet; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class CharacterEncodingFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 設置請求時的編碼方法 request.setCharacterEncoding("utf-8"); // 調用web資源,也可以調用其他過濾器 chain.doFilter(request, response); // 設置響應時的編碼方式 response.setCharacterEncoding("utf-8"); } public void init(FilterConfig arg0) throws ServletException { } }
再創建MyFilter過濾器類
package demo.web.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class MyFilter implements Filter { public void destroy() { // TODO Auto-generated method stub } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub request.setCharacterEncoding("utf-8"); System.out.println("myFilter調用doFilter開始"); chain.doFilter(request, response); response.setCharacterEncoding("utf-8"); System.out.println("myFilter調用doFilter結束"); } public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } }
<filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>demo.web.filter.CharacterEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> <!-- 過濾站點的所有信息,配置與servlet類似可以是/xx/*或者/xx --> </filter-mapping>
<filter> <display-name>myFilter</display-name> <filter-name>myFilter</filter-name> <filter-class>demo.web.filter.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>myFilter</filter-name> <url-pattern>/*</url-pattern> <!-- 過濾站點的所有信息 --> <dispatcher>REQUEST</dispatcher> </filter-mapping>
<dispatcher>指定過濾器所攔截的資源被 Servlet 容器調用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默認REQUEST。用戶可以設置多個
<dispatcher> 子元素用來指定 Filter 對資源的多種調用方式進行攔截。
<dispatcher> 子元素可以設置的值及其意義:
1.REQUEST:當用戶直接訪問頁面時,Web容器將會調用過濾器。如果目標資源是通過RequestDispatcher的include()或forward()方法訪問時,那麼該過濾器就不會被調用。
2.INCLUDE:如果目標資源是通過RequestDispatcher的include()方法訪問時,那麼該過濾器將被調用。除此之外,該過濾器不會被調用。
3.FORWARD:如果目標資源是通過RequestDispatcher的forward()方法訪問時,那麼該過濾器將被調用,除此之外,該過濾器不會被調用。
4.ERROR:如果目標資源是通過聲明式異常處理機制調用時,那麼該過濾器將被調用。除此之外,過濾器不會被調用。
在web應用中可以開發多個Filter過濾器,這些Filter組合起來就是一個Filter鏈。
web服務器根據Filter在web.xml文件中的注冊順序,決定先調用哪個Filter,當第一個Filter的doFilter方法被調用時,web服務器會創建一個代表Filter鏈的FilterChain對象傳遞
給該方法。在doFilter方法中,開發人員如果調用了FilterChain對象的doFilter方法,則web服務器會檢查FilterChain對象中是否還有filter,如果有,則調用第2個filter,如果沒
有,則調用目標資源。
還有創建servlet,已在上一篇servlet文章中創建
在浏覽器中調用http://localhost:8080/servletDemo/myServlet,在控制台輸出
有運行結果分析可知道:過濾是按照web.xml中配置的順序先調用servlet的初始化,再調用CharacterEncodingFilter的doFilter方法,在程序執行到chain.doFilter(req,resp);
方法時會去調用web.xml中配置的characterEncodingFilter下邊的Filter,也就是調用MyFilter中的doFilter()方法,過濾器這種嵌套執行完後才調用servlet的doGet()方法;
注意:這個過程servlet只會初始化一次,並且servlet初始化後不會再調用Filter的init()方法,Filter位於javax.servlet.filter包下。