1.利用Filter來過濾的時候大都是Http請求和Http響應,在doFilter()方法中,參數類是ServletRequest和ServletResponse ,使用的時候一般需要強制轉換為HttpServletRequest和HttpServletResponse 。針對這個問題,可以仿照G ...
1.利用Filter來過濾的時候大都是Http請求和Http響應,在doFilter()方法中,參數類是ServletRequest和ServletResponse ,使用的時候一般需要強制轉換為HttpServletRequest和HttpServletResponse 。針對這個問題,可以仿照GenericServlet 的做法,來定義一個HttpFilter,用作所有Filter的父類。
HttpFilter.java
package com.javaweb.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;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public abstract class HttpFilter implements Filter {
@Override
public void destroy() { }
/*
* 原生的doFilter方法,在方法內部把ServletRequest和ServletResponse轉為了HttpServletRequest和HttpServletResponse,
* 並調用了doFilter(HttpServletRequest request,HttpServletResponse response,FilterChain filterchain)方法。
* 若編寫Filter的過濾方法不建議直接繼承該方法,而建議繼承doFilter(HttpServletRequest request,HttpServletResponse response,
* FilterChain filterchain)方法。
* */
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterchain)
throws IOException, ServletException {
HttpServletRequest request=(HttpServletRequest) req;
HttpServletResponse response=(HttpServletResponse) resp;
doFilter(request,response,filterchain);
}
//抽象方法,為Http請求定製必須實現的方法。
public abstract void doFilter(HttpServletRequest request,HttpServletResponse response,FilterChain filterchain) throws IOException, ServletException;
private FilterConfig filterconfig;
//不建議子類直接覆蓋,若直接覆蓋,將可能會導致filterConfig成員變數初始化失敗。
@Override
public void init(FilterConfig filterconfig) throws ServletException {
this.filterconfig =filterconfig;
init();
}
//供子類繼承的初始化方法,可以通過getFilterConfig()獲取FilterConfig對象。
public void init(){}
//直接返回init(ServletConfig)的ServletConfig對象。
public FilterConfig getFilterConfig(){
return filterconfig;
}
}
2.理解多個Filter代碼的執行順序
示例代碼:
index.html
<body> <a href="http://localhost:8080/MyWebProject/jspTest/test.jsp">to test jsp page</a> </body>
test.jsp
<body> <% System.out.println("5. Test page"); %> </body>
過濾器攔截:
filterTest.java
package com.javaweb.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 filterTest implements Filter { @Override public void destroy() { System.out.println("destroy..."); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("1. before filterTest's chain.doFilter..."); chain.doFilter(request,response); System.out.println("2. after filterTest's chain.doFilter..."); } @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("init..."); } }
secondFilter.java
package com.javaweb.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 secondFilter implements Filter { @Override public void destroy() { System.out.println("secondFilter's destroy..."); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("3. before secondFilter's chain doFilter..."); chain.doFilter(request,response); System.out.println("4. after secondFilter's chain doFilter..."); } @Override public void init(FilterConfig arg0) throws ServletException { System.out.println("secondFilter's init..."); } }
在web.xml中進行配置:
<filter> <filter-name>filterTest</filter-name> <filter-class>com.javaweb.Filter.filterTest</filter-class> </filter> <filter-mapping> <filter-name>filterTest</filter-name> <url-pattern>/jspTest/test.jsp</url-pattern> </filter-mapping> <filter> <filter-name>secondFilter</filter-name> <filter-class>com.javaweb.Filter.secondFilter</filter-class> </filter> <filter-mapping> <filter-name>secondFilter</filter-name> <url-pattern>/jspTest/test.jsp</url-pattern> </filter-mapping>
執行順序:
index.html頁面點擊鏈接時去test.jsp頁面,被第一個過濾器filterTest攔截,
①首先執行其中的doFilter()方法,執行方法體中的System.out.println("1. before filterTest's chain.doFilter...");
②之後chain.doFilter(request,response);將攔截傳遞給下一個過濾器secondFilter,執行其中的doFilter()方法,同樣執行方法體中的System.out.println("3. before secondFilter's chain doFilter...");
③接著chain.doFilter(request,response);因為沒有過濾器,所以將請求轉發到test.jsp,執行<% System.out.println("5. Test page"); %>;
④接下來執行方法體中的System.out.println("4. after secondFilter's chain doFilter...");
⑤最後回到filterTest的doFilter()方法中,執行System.out.println("2. after filterTest's chain.doFilter...");
3.<dispatcher>
<dispatcher></dispatcher>指定過濾器所攔截的資源被Servlet容器調用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,預設為REQUEST。可以設置多個<dispatcher>子元素來指定Filter對資源的多種調用方式進行攔截。
<dispatcher>子元素可以設置的值及其意義:
REQUEST:當用戶直接訪問頁面時,Web容器將會調用過濾器。如果目標資源是通過RequestDispatcher的include()或forward()方法訪問時,那麼該過濾器將不會被調用。
INCLUDE:如果目標資源是通過RequestDispatcher的include()方法訪問時,那麼該過濾器將會被調用,除此之外,該過濾器不會被調用。
FORWARD:如果目標資源是通過RequestDispatcher的forward()方法訪問時,那麼該過濾器將會被調用,除此之外,該過濾器不會被調用。
ERROR:如果目標資源是通過聲明式異常處理機制調用時,那麼該過濾器將會被調用,除此之外,過濾器不會被調用。