據說你叫Java(三)–Servlet過濾器

據說你改bug很厲害,幫我改一個吧
????
0?wx_fmt=gifhtml

上一章咱們講到了Servlet請求,能夠經過瀏覽器發送的請求,來進行數據的處理並返回相應的響應給瀏覽器。前端

在咱們的實際開發中,經常會遇到一些對全部方法都須要的驗證方法,好比登陸驗證等,這個時候咱們在每一個方法中都編寫一樣的功能代碼,既浪費時間也不利於維護。java

幸虧,Servlet給咱們提供了過濾器解決這個問題。web

是什麼

Servlet 過濾器能夠動態地攔截請求和響應,以變換或使用包含在請求或響應中的信息。編程

能夠將一個或多個 Servlet 過濾器附加到一個 Servlet 或一組 Servlet。調用 Servlet 前調用全部附加的 Servlet 過濾器。後端

Servlet 過濾器能夠實現如下目的:瀏覽器

  • 在客戶端的請求訪問後端資源以前,攔截這些請求。服務器

  • 在服務器的響應發送回客戶端以前,處理這些響應。app

一樣的,Servlet過濾器是可用於 Servlet 編程的 Java 類,也須要在XML中聲明的。Filter執行順序和在web.xml中聲明的順序一致,一般把Filter配置在全部邏輯Servlet以前。學習

如何用

Servlet經過javax.servlet.Filter接口來實現過濾器,接口提供了三個方法:

public void doFilter(ServletRequest, ServletResponse, FilterChain)

該方法完成實際的過濾操做,當客戶端請求方法與過濾器設置的URL匹配時,Servlet容器將先調用過濾器的doFilter方法。FilterChain用戶訪問後續過濾器。

public void init(FilterConfig filterConfig)

web 應用程序啓動時,web 服務器將建立Filter 的實例對象,並調用其init方法,讀取web.xml配置,完成對象的初始化功能,從而爲後續的用戶請求做好攔截的準備工做(filter對象只會建立一次,init方法也只會執行一次)。開發人員經過init方法的參數,可得到表明當前filter配置信息的FilterConfig對象

public void destroy()

Servlet容器在銷燬過濾器實例前調用該方法,在該方法中釋放Servlet過濾器佔用的資源。

配置過濾器web.xml節點說明
節點 說明
<filter> 指定這個過濾器
<filter-name> 過濾器的名稱
<filter-class> 過濾器完整類名
<init-param> 元素用於爲過濾器指定初始化參數,它的子元素<param-name>指定參數的名字,<param-value>指定參數的值。
<filter-mapping> 元素用於設置一個 Filter 所負責攔截的資源。一個Filter攔截的資源可經過兩種方式來指定:Servlet 名稱和資源訪問的請求路徑
<filter-name> 子元素用於設置filter的註冊名稱。該值必須是在<filter>元素中聲明過的過濾器的名字
<url-pattern> 設置 filter 所攔截的請求路徑(過濾器關聯的URL樣式)

0?wx_fmt=png

舉個例子

咱們接着上一章的小栗子繼續擴展咱們的應用。

1. 新建一個class類,這裏須要注意的是,若是咱們要在過濾器中返回值給瀏覽器,須要引入相應的庫才行。
package com.filter;

//導入必要的依賴庫
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;

//實現Filter類
public class FirstFilter implements Filter {
    public void init(FilterConfig config) throws ServletException {
        //獲取web.xml中初始化的參數
        String name = config.getInitParameter("name");
        //輸出
        System.out.println("請關注:"+ name);
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)  throws java.io.IOException, ServletException {
        System.out.println("我在doFilter中");
        
        String message = "我跨越過濾器來跟你說";
        // 設置響應內容類型
        response.setContentType("text/html;charset=utf-8");
        // 實際的邏輯是在這裏
        PrintWriter out = response.getWriter();
        out.println("<h1>" + message + "</h1>");
        //把請求傳回過濾鏈
        chain.doFilter(request, response);
    }
    public void destroy(){
        //do something
    }
}
2. web.xml中一樣配置好,將過濾器添加到servlet的上方
<web-app>
  <filter>
      <filter-name>FirstFilter</filter-name>
      <filter-class>com.filter.FirstFilter</filter-class>
      <init-param>
        <param-name>name</param-name>
        <param-value>野生前端攻城獅</param-value>
      </init-param>
  </filter>
  <filter-mapping>
      <filter-name>FirstFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
  <servlet>
      <servlet-name>HelloWorld</servlet-name>
      <servlet-class>com.servletLearn.HelloWorld</servlet-class>
  </servlet>

  <servlet-mapping>
      <servlet-name>HelloWorld</servlet-name>
      <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>
3. 看結果

能夠看到,咱們在項目啓動的時候,執行了Filter的init()方法,因此在服務器日誌中看到了打印請關注野生前端攻城獅字符串。

0?wx_fmt=png

使用瀏覽器打開對應的連接時,一樣在服務器日誌中也出現了咱們打印的字符串。而在瀏覽器中,則同時出現了咱們在過濾器和HelloWorld方法中返回的字符串。

0?wx_fmt=png

因此,咱們在過濾器中返回的值,並無影響原來Servlet方法的執行。

最後

過濾器在平常開發中適用範圍很是普遍,因此是咱們學習servlet所必需要掌握的一個知識點。

PS:過濾器和攔截器是兩個徹底不一樣的概念。過濾器是原生servlet的類,攔截器是Spring及struts2裏的概念

0?wx_fmt=jpeg

相關文章
相關標籤/搜索