本人博客:http://wxmimperio.coding.io/
本人郵箱:wxmimperio@163.com
本文源碼——GitHub:
https://github.com/imperio-wxm/WordPRessCode/tree/master/Filter
【沒有過濾器】:
用戶直接訪問WEB資源。
【有過濾器】:
WEB容器啟動時進行過濾器的加載,用戶發出請求到過濾器,過濾器判斷請求是否符合規則,符合規則的請求通過過濾器發送給WEB資源,WEB資源響應的信息返回給過濾器,過濾器再將WEB資源的響應返回給用戶。
1.實例化——通過web.xml進行配置加載,在容器啟動時只會實例化一次2.初始化——調用init()方法,加載信息只會執行一次3.過濾——使用doFilter()方法進行多次過濾4.銷毀——WEB容器關閉時調用destroy()方法進行銷毀
所有的Servlet過濾器都必須實現javax.servlet.Filter接口,并實現該接口中的三個方法。
【init()方法】【生命周期代碼演示】
package com.filter;import javax.servlet.*;import java.io.IOException;/** * Created by wxm-Imperio */public class FirstFilter implements Filter { @Override public void destroy() { System.out.println("destroy,firstFilter"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("start,doFilter,firstFilter"); filterChain.doFilter(servletRequest, servletResponse); System.out.println("End,doFilter,firstFilter"); } @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("init。firstFilter"); }}【web.xml配置】
<filter> <filter-name>Filter的名字</filter-name> <filter-class>Filter類的名字</filter-class> <init-param> <description>描述信息可以省略或者放在此處</description> <param-name>參數名稱</param-name> <param-value>參數的值</param-value> </init-param></filter><filter-mapping> <filter-name>Filter的名字</filter-name> <url-pattern>URL</url-pattern> <dispatcher></dispatcher>//過濾器類型</filter-mapping>
注意:一般Filter配置在所有的Servlet之前。
【過濾器鏈的web.xml配置】
<!--過濾器1的配置信息--!><filter> <filter-name>Filter1的名字</filter-name> <filter-class>Filter1類的名字</filter-class> <init-param> <description>描述信息可以省略或者放在此處</description> <param-name>參數名稱</param-name> <param-value>參數的值</param-value> </init-param></filter><filter-mapping> <filter-name>Filter1的名字</filter-name> <url-pattern>URL</url-pattern> <dispatcher></dispatcher>//過濾器類型</filter-mapping><!--過濾器2的配置信息--!><filter> <filter-name>Filter2的名字</filter-name> <filter-class>Filter2類的名字</filter-class> <init-param> <description>描述信息可以省略或者放在此處</description> <param-name>參數名稱</param-name> <param-value>參數的值</param-value> </init-param></filter><filter-mapping> <filter-name>Filter2的名字</filter-name> <url-pattern>URL</url-pattern> <dispatcher></dispatcher>//過濾器類型</filter-mapping>
注意:過濾器的執行順序就是在web.xml里配置的順序。
Servlet2.5:
1.REQUEST(默認)用戶直接訪問頁面時,web容器將會調用過濾器。2.FORWORD 目標源是通過RequestDispatcher的forword方法訪問時,該過濾器被調用。3.INCLUDE 目標資源時通過RequestDispatcher的include方法調用時,過濾器被調用。4.ERROR 目標資源是通過聲明式異常處理機制調用時,過濾器將被調用。【語法】@WebFilter(servletNames = {"SimpleServlet"} filterName = "SimpleFilter")public class LessThanSixFilter implements Filter {//類中內容}【ERROR的配置信息】
<error-page> <error-code>404</error-code> <location>/error.jsp</location></error-page><filter> <filter-name>errorFilter</filter-name> <filter-class>com.filter.ErrorFilter</filter-class></filter><filter-mapping> <filter-name>errorFilter</filter-name> <url-pattern>/error.jsp</url-pattern></filter-mapping>
【ErrorFilter過濾器代碼】
public class ErrorFilter implements Filter { @Override public void destroy() { } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("檢測到有錯誤信息"); }}Servlet3.0:
(新增)ASYNC 支持異步處理【異步操作處理代碼:過濾器不等待線程,直接執行后面內容,實現異步處理】
AsynServlet
//設置Servlet支持異步@WebServlet(name = "AsynServlet", asyncSupported = true)public class AsynServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("Servlet執行開始時間" + new Date()); //實現異步操作 AsyncContext context = request.startAsync(); //開啟異步線程 new Thread(new Executor(context)).start(); System.out.println("Servlet執行結束時間" + new Date()); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } //內部類模擬線程 public class Executor implements Runnable { private AsyncContext context; //實現構造方法 public Executor(AsyncContext context) { this.context = context; } @Override public void run() { //執行相關的復雜業務 try { Thread.sleep(1000 * 10); //context.getRequest(); //context.getResponse(); System.out.println("業務執行完成時間" + new Date()); } catch (InterruptedException e) { e.printStackTrace(); } } }}AsvnFilter過濾器
//注解@WebFilter(filterName = "AsynFilter", value = {"/AsynServlet"}, asyncSupported = true, dispatcherTypes = {DispatcherType.REQUEST,DispatcherType.ASYNC})public class AsynFilter implements Filter { @Override public void destroy() { } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("Start..........AsynFilter"); filterChain.doFilter(servletRequest, servletResponse); System.out.println("End..........AsynFilter"); }}web.xml配置
<servlet> <servlet-name>AsynServlet</servlet-name> <servlet-class>com.servlet.AsynServlet</servlet-class></servlet><servlet-mapping> <servlet-name>AsynServlet</servlet-name> <url-pattern>/AsynServlet</url-pattern></servlet-mapping>
Filter的init方法中提供了一個FilterConfig對象,提供相關的操作:
如獲取Filter中配置的初始化參數web.xml配置:
<filter> <filter-name>LoginFilter</filter-name> <filter-class>com.itzhai.login.LoginFilter</filter-class> <init-param> <param-name>username</param-name> <param-value>arthinking</param-value> </init-param></filter>
在init()方法中獲取:
@Overridepublic void init(FilterConfig filterConfig) throws ServletException { //獲取Filter初始化參數 String username = filterConfig.getInitParameter("username");}在Filter中訪問application:
ServletContext context = filterConfig.getServletContext();
也可以在doFilter方法中根據轉換好的request獲取:
HttpServletRequest req = (HttpServletRequest)request;ServletContext context = req.getsession().getServletContext();
慕課網中用戶登錄的加強版Demo,利用過濾器對用于請求和服務器回應進行過濾。
GitHub源碼:https://github.com/imperio-wxm/projectDemo
參考:JSP應用開發詳解(第三版)、慕課網
新聞熱點
疑難解答