過濾器
過濾器的作用
對請求作統一處理(如編碼格式,過濾無效數據,驗證用戶權限等)之後再執行servlet中的代碼,而不用每次都在servlet中處理,這樣大大減少了重複勞動的工作
原理
- 當用戶訪問服務器時,請求先被過濾器攔截下來(如果有過濾器的時候)
- 在過濾器裏面進行處理(具體在doFilter()方法中)
在doFilter()方法裏面調用chain.doFilter(request, response);如果有其他的過濾器就進入下一個過濾器如果沒有,就進入用戶訪問的資源(servlet或者jsp等) - 執行完servlet裏面的代碼後還要返回到過濾器中(有多個過濾器時,逐個返回)
多個過濾器的執行順序
1、如果是在xml中配置的過濾器
則按照xml中的先後執行
2、如果是通過註解@WebFilter(“/*”)的方式配置的過濾器
則按照字符串比較大小的方式將過濾器的類名進行比較,排序小的先執行
過濾器的生命週期
- 在服務器啓動的時候構造過濾器對象並初始化
1、調用構造方法
2、調用init()方法 - 用戶向服務器發來請求的時候執行doFilter()
3、調用doFilter()方法 - Reload項目或者關閉服務器的時候銷燬所有的對象
4、調用destroy()
簡單代碼演示
@WebFilter("/*")
public class TestFilter_1 implements Filter{
/**
* 構造方法和初始化方法在服務器啓動的時候就執行完畢
*/
public TestFilter_1() {
System.out.println("構造器");
}
@Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println("初始化方法");
}
/**
* 該方法是用戶發來請求的時候執行
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("進入TestFilter_1");
//放行,如果還有過濾器就進入下一個過濾器
chain.doFilter(request, response);
System.out.println("執行完doFilter,回到TestFilter_1");
}
/**
* 服務器停止的時候銷燬(重新加載的時候)
*/
@Override
public void destroy() {
System.out.println("銷燬過濾器");
}
}
@WebFilter("/*")
public class TestFilter_2 implements Filter {
public TestFilter_2() {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("進入HelloFilter2");
chain.doFilter(request, response);
System.out.println("執行完doFilter,回到TestFilter_2");
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
@WebServlet("/index")
public class IndexServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("處理開始請求");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
控制檯打印結果
進入TestFilter_1
進入HelloFilter2
處理開始請求
執行完doFilter,回到TestFilter_2
執行完doFilter,回到TestFilter_1