1.過濾器的概念
Java中的Filter 並不是一個標准的Servlet ,它不能處理用戶請求,也不能對客戶端生成響應。 主要用於對HttpServletRequest 進行預處理,也可以對HttpServletResponse 進行后處理,是個典型的處理鏈。
優點:過濾鏈的好處是,執行過程中任何時候都可以打斷,只要不執行chain.doFilter()就不會再執行后面的過濾器和請求的內容。而在實際使用時,就要特別注意過濾鏈的執行順序問題
2.過濾器的作用描述
- 在HttpServletRequest 到達Servlet 之前,攔截客戶的HttpServletRequest 。
- 根據需要檢查HttpServletRequest ,也可以修改HttpServletRequest 頭和數據。
- 在HttpServletResponse 到達客戶端之前,攔截HttpServletResponse 。
- 根據需要檢查HttpServletResponse ,可以修改HttpServletResponse 頭和數據。
3.過濾器的執行流程
4.Filter接口
1.如何驅動
在 web 應用程序啟動時,web 服務器將根據 web.xml 文件中的配置信息來創建每個注冊的 Filter 實例對象,並將其保存在服務器的內存中
2.方法介紹
- init() Init 方法在 Filter 生命周期中僅執行一次,web 容器在調用 init 方法時
- destory() 在Web容器卸載 Filter 對象之前被調用。該方法在Filter的生命周期中僅執行一次。在這個方法中,可以釋放過濾器使用的資源。
- doFilter() Filter 鏈的執行
5.FilterChain接口
1.如何實例化
代表當前 Filter 鏈的對象。由容器實現,容器將其實例作為參數傳入過濾器對象的doFilter()方法中
2.作用
調用過濾器鏈中的下一個過濾器
filter實例:
web.xml配置
<!-- 編碼過濾器 --> <filter> <filter-name>setCharacterEncoding</filter-name> <filter-class>com.company.strutstudy.web.servletstudy.filter.EncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>setCharacterEncoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 請求url日志記錄過濾器 --> <filter> <filter-name>logfilter</filter-name> <filter-class>com.company.strutstudy.web.servletstudy.filter.LogFilter</filter-class> </filter> <filter-mapping> <filter-name>logfilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
編碼攔截器:
public class EncodingFilter implements Filter { private String encoding; private Map<String, String> params = new HashMap<String, String>(); // 項目結束時就已經進行銷毀 public void destroy() { System.out.println("end do the encoding filter!"); params=null; encoding=null; } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { //UtilTimerStack.push("EncodingFilter_doFilter:"); System.out.println("before encoding " + encoding + " filter!"); req.setCharacterEncoding(encoding); // resp.setCharacterEncoding(encoding); // resp.setContentType("text/html;charset="+encoding); chain.doFilter(req, resp); System.out.println("after encoding " + encoding + " filter!"); System.err.println("----------------------------------------"); //UtilTimerStack.pop("EncodingFilter_doFilter:"); } // 項目啟動時就已經進行讀取 public void init(FilterConfig config) throws ServletException { System.out.println("begin do the encoding filter!"); encoding = config.getInitParameter("encoding"); for (Enumeration e = config.getInitParameterNames(); e .hasMoreElements();) { String name = (String) e.nextElement(); String value = config.getInitParameter(name); params.put(name, value); } } }
日志攔截器:
public class LogFilter implements Filter { FilterConfig config; public void destroy() { this.config = null; } public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { // 獲取ServletContext 對象,用於記錄日志 ServletContext context = this.config.getServletContext(); //long before = System.currentTimeMillis(); System.out.println("before the log filter!"); //context.log("開始過濾"); // 將請求轉換成HttpServletRequest 請求 HttpServletRequest hreq = (HttpServletRequest) req; // 記錄日志 System.out.println("Log Filter已經截獲到用戶的請求的地址:"+hreq.getServletPath() ); //context.log("Filter已經截獲到用戶的請求的地址: " + hreq.getServletPath()); try { // Filter 只是鏈式處理,請求依然轉發到目的地址。 chain.doFilter(req, res); } catch (Exception e) { e.printStackTrace(); } System.out.println("after the log filter!"); //long after = System.currentTimeMillis(); // 記錄日志 //context.log("過濾結束"); // 再次記錄日志 //context.log(" 請求被定位到" + ((HttpServletRequest) req).getRequestURI() // + "所花的時間為: " + (after - before)); } public void init(FilterConfig config) throws ServletException { System.out.println("begin do the log filter!"); this.config = config; } }
HelloServlet類:
public class HelloWorldServlet extends HttpServlet{ /** * 查看httpservlet實現的service一看便知,起到了一個controll控制器的作用(轉向的) * 之后便是跳轉至我們熟悉的doget,dopost等方法中 */ @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doservice..."+this.getInitParameter("encoding")); super.service(req, resp); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doget..."); doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("dopost..."); } }
結果:
before encoding utf-8 filter! before the log filter! Log Filter已經截獲到用戶的請求的地址:/hello doservice...UTF-8 doget... dopost... after the log filter! after encoding utf-8 filter! ----------------------------------------
總結:
1.過濾器執行流程
2.常用過濾器
<pre name="code" class="plain"><pre></pre><pre name="code" class="plain"></pre><pre></pre> <pre></pre> <pre></pre> <pre></pre> <pre></pre> <pre></pre> <pre></pre> <link rel="stylesheet" href="http://static.blog.csdn.net/public/res-min/markdown_views.css?v=2.0"> </pre>