在Servlet2.3規範中定義了過濾器,它對servlet容器調用servlet的過程進行攔截,從而在servlet進行響應處理的先後實現一些特殊的功能。 java
過濾器實現了一個責任鏈的模式。多個過濾器造成一個過濾器鏈,過濾器鏈中不一樣過濾器的前後順序由部署文件web.xml中過濾器映射<filter-mapping>的順序決定。 web
最早截獲客戶端請求的過濾器將最後截獲Servlet/JSP的響應信息。 瀏覽器
Servlet過濾器能夠過濾的Web組件包括Servlet,JSP和HTML等文件。 緩存
Servlet過濾器能夠應用在客戶端和servlet之間、servlet和servlet或JSP頁面之間,以及所包括的每一個JSP頁面之間。 tomcat
全部的Servlet過濾器都必須實現javax.servlet.Filter接口,並實現該接口中的三個方法: app
init(FilterConfig filterConfig) jsp
Servlet過濾器的初始化方法,Servlet容器建立Servlet過濾器實例後將調用該方法。該方法將讀取web.xml文件中Servlet過濾器的初始化參數。 ide
該方法在tomcat啓動的時候執行。doFilter(ServletRequest request, ServletResponse response, FilterChain chain) ui
該方法完成實際的過濾操做,當客戶端請求方法與過濾器設置匹配的URL時,Servlet容器將先調用過濾器的doFilter方法。FilterChain用戶訪問後續過濾器。 編碼
這裏的ServletRequest和ServletResponse通常須要轉換成具體的Servlet實現對於的對象,如:HttpServletRequest和HttpServletResponse。
有些過濾器比較消耗資源,因此須要防止重複過濾,能夠在doFilter()方法中判斷。
destroy()
Servlet容器在銷燬過濾器實例前調用該方法,在該方法中釋放Servlet過濾器佔用的資源。
Filter的init方法中提供了一個FilterConfig對象,提供相關的操做:
如獲取Filter中配置的初始化參數:<filter> <filter-name>LoginFilter</filter-name> <filter-class>cn.heimar.LoginFilter</filter-class> <init-param> <param-name>username</param-name> <param-value>admin</param-value> </init-param> </filter>在init方法中獲取:
@Override public void init(FilterConfig filterConfig) throws ServletException { //獲取Filter初始化參數 String username = filterConfig.getInitParameter("username"); }
ServletContext context = filterConfig.getServletContext();或者在doFilter方法中根據轉換好的request獲取:
HttpServletRequest req = (HttpServletRequest)request; ServletContext context = req.getSession().getServletContext();
public class MyFilter implements Filter { public void init(FilterConfig fc) { //過濾器初始化代碼 } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain){ //在這裏能夠對客戶端請求進行檢查 //沿過濾器鏈將請求傳遞到下一個過濾器。 chain.doFilter(request, response); //在這裏能夠對響應進行處理 } public void destroy( ) { //過濾器被銷燬時執行的代碼 } }
<filter> <filter-name>MyFilter</filter-name> <filter-class> cn.edu.uibe.webdev.MyFilter </filter-class> <init-param> <param-name>developer</param-name> <param-value>TongQiang</param-value> </init-param> </filter> <!--針對一個Servlet作過濾--> <filter-mapping> <filter-name>MyFilter</filter-name> <servlet-name>MyServlet</servlet-name> </filter-mapping> <!--針對URL Pattern作過濾--> <filter-mapping> <filter-name>MyFilter</filter-name> <url-pattern>/book/*</url-pattern> </filter-mapping>
/* 攔截全部資源及不存在的資源
*.jsp 攔截全部jsp文件
默認狀況下forward方式不會被過濾。通常是須要過濾的,方式是在filter-mapping中添加<dispatcher>FORWARD</dispatcher>,該值默認是request,添加時爲了防止覆蓋request,須要把該值也添加。能夠驗證用戶是否登陸。
對客戶端提交的數據進行從新編碼示例:
EncodingFilter.java
package cn.heimar.filter.encoding; 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; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class EncodingFilter implements Filter { /** * 設置編碼格式 */ private String encoding; /** * 是否須要強制轉碼 */ private boolean forceEncoding = false; @Override public void init(FilterConfig config) throws ServletException { encoding = config.getInitParameter("ENCODING"); String force = config.getInitParameter("FORCE_ENCODING"); if (force != null) forceEncoding = Boolean.valueOf(force); } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; if ((request.getCharacterEncoding() == null || forceEncoding) && encoding != null){ request.setCharacterEncoding(encoding); } response.setCharacterEncoding(encoding); chain.doFilter(req, resp); } @Override public void destroy() { } }web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <filter> <filter-name>EncodingFilter</filter-name> <filter-class>cn.heimar.filter.encoding.EncodingFilter</filter-class> <!-- 配置編碼格式 --> <init-param> <param-name>ENCODING</param-name> <param-value>utf-8</param-value> </init-param> <!-- 配置是否強轉 --> <init-param> <param-name>FORCE_ENCODING</param-name> <param-value>true</param-value> </init-param> </filter> <servlet> <servlet-name>LoginServlet</servlet-name> <servlet-class>cn.heimar.filter.encoding.LoginServlet</servlet-class> </servlet> <filter-mapping> <filter-name>EncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet-mapping> <servlet-name>LoginServlet</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping> </web-app>