JavaWeb三大元件(Servlet、Filter、Listener)

2022-12-07 21:02:31

前言

JavaWeb三大元件指的是:Servlet 程式、Filter 過濾器、Listener 監聽器,它們在JavaWeb開發中分別提供不同的功能,然而很多人有隻用過Servlet、Filter,很少接觸到Listener,甚至有些人對然而很多人有隻用過Servlet都不熟悉,因為在企業開發中,都是使用框架的封裝好的,很少接觸到原生的JavaWeb元件,充其量就是使用Filter攔截請求,過濾響應,所以很多人上來就直接學框架。

其實這種做法很不可取,雖然隨著技術的發展,已經沒有人再使用原生JavaWeb開發了,加之前後端分離,像JSP、JDBC等技術都沒有了專門學習的必要了。但是JavaWeb的三大元件卻是十分重要,框架都是對原生JavaWeb進行封裝的結果,像SpringMVC的核心就是Servlet,涉及到Listener的框架就更多了,而Filter不僅在框架使用,日常開發中也經常被用到,所以要深入理解框架,就必須熟練掌握JavaWeb的三大元件。

一、Servlet 程式

Servlet是什麼?

Servlet是JavaEE規範(介面)之一;
Servlet是執行在伺服器(Web容器Tomcat等)上的一個 java 小程式,它用來接收使用者端傳送過來的請求進行處理,並響應資料給使用者端
Servlet及相對的物件,都由Tomcat建立,我們只是使用。

Servlet需要完成3個任務:

  1. 接收請求:將使用者端傳送過來的請求封裝成ServletRequest物件(包含請求頭、引數等各種資訊)
  2. 處理請求:在service方法中接收引數,並且進行處理請求。
  3. 資料響應:請求處理完成後,通過轉發(forward)或者重定向(redirect)到某個頁面。
    轉發(forward)或者重定向(redirect)的區別?
    本質:forward是HttpServletRequest的方法,redirect是HttpServletResponse的方法。
    現象及結果:
    1. forward使用者端只發了一次請求,在伺服器端進行轉發行為,可以共用資料(request中引數),瀏覽器URL不改變。
    2. redirect是伺服器端向用戶端完成響應後,使用者端再次發起一個請求,不可以共用資料(request中引數),請求了兩次,瀏覽器URL改變。
    

Servlet的生命週期

  1. 執行 Servlet 構造器方法
    第一步,在web.xml中的servlet中設定 load-on-startup 的值 ≥ 0 時,表示應用啟動時就建立這個servlet。否則,第一次存取的時候呼叫。

  2. 執行 init 初始化方法
    第二步,第一次存取的時候呼叫。

  3. 執行 service 方法
    第三步,每次存取都會呼叫。

  4. 執行 destroy 銷燬方法
    第四步,在 web 工程停止的時候呼叫。

通過實現 Servlet 介面 實現Servlet程式

  1. 實現Servlet介面,重寫service方法,處理請求,並響應資料
  2. 在web.xml中設定servlet程式的存取地址。

web.xml 中的設定:

    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.demo.servlet.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

通過繼承 HttpServlet 實現Servlet程式(推薦,一般開發中使用這種方式)

  1. 繼承 HttpServlet類,按業務需求重寫doGet 或 doPost 方法,處理請求
  2. 到 web.xml 中的設定 Servlet 程式的存取地址

程式碼比實現Servlet介面的方式更加簡單,不需要進行請求的型別轉換,設定與實現Servlet介面的方式一樣,所以這裡不做演示

ServletConfig(Servlet程式的設定資訊類)

在Servlet 程式建立時,就會建立一個對應的 ServletConfig 物件。

它的三大作用:

  1. 獲取web.xml 中 Servlet 程式的別名 servlet-name 的值
  2. 獲取web.xml 中 Servlet 程式的獲取初始化引數 init-param
  3. 獲取 ServletContext 物件

ServletContext (Servlet上下文) 介面

  1. 每個web專案只有一個ServletContext物件,在web工程部署啟動的時候建立,在工程停止的時候關閉。
  2. ServletContext 物件是一個域物件(可以像Map一樣儲存資料的物件。域指的是作用域,這裡是整個web工程)。

ServletContext 類的四個作用:

  1. 獲取 web.xml 中設定的上下文引數 context-param
  2. getContextPath()獲取當前的工程路徑,格式: /工程路徑
  3. getRealPath()獲取工程部署後在伺服器硬碟上的絕對路徑
  4. 像 Map 一樣存取資料

HttpServletRequest 和 HttpServletResponse

HttpServletRequest

HttpServletRequest繼承了ServletRequest,每次請求進入tomcat伺服器,tomcat容器就會把請求過來的 HTTP 協定資訊解析好封裝到 Request 物件中。然後傳遞到 service 方法(doGet 和 doPost)中給我們使用。我們可以通過 HttpServletRequest 物件,獲取到所有請求的資訊

HttpServletResponse

HttpServletResponse 類和 HttpServletRequest 類一樣。每次請求進來,Tomcat 伺服器都會建立一個 Response 物件傳遞給 Servlet 程式去使用。通過 HttpServletResponsee 物件來進行設定返回給使用者端的資訊

解決請求的中文亂碼

  1. Get請求:獲取請求引數,先以 iso8859-1 進行編碼,再以 utf-8 進行解
  2. Post請求:呼叫req.setCharacterEncoding("UTF-8"), 設定請求體的字元集為 UTF-8;

解決響應的中文亂碼

方案一(推薦):

// 它會同時設定伺服器和使用者端都使用 UTF-8 字元集,還設定了響應頭
// 此方法一定要在獲取流物件之前呼叫才有效
resp.setContentType("text/html; charset=UTF-8")

方案二(不推薦):

// 設定伺服器字元集為 UTF-8
resp.setCharacterEncoding("UTF-8");
// 通過響應頭,設定瀏覽器也使用 UTF-8 字元集
resp.setHeader("Content-Type", "text/html; charset=UTF-8"

Filter

Filter 是JavaEE規範(介面)之一;
Filter 過濾器它的作用是:攔截請求,過濾響應。

常見應用場景:
1、許可權檢查
2、日記操作
3、事務管理
……等等

Filter 過濾器的使用步驟:

1、實現 Filter 介面,實現過濾方法 doFilter()
2、到 web.xml 中去設定 Filter 的攔截路徑

web.xml 中的設定:

<filter>
    <filter-name>AdminFilter</filter-name>
    <filter-class>com.demo.filter.AdminFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>AdminFilter</filter-name>
    <url-pattern>/admin/*</url-pattern>
</filter-mapping>

Filter 的生命週期

  1. 構造器方法
  2. init 初始化方法
    第 1,2 步,在 web 工程啟動的時候執行(Filter 已經建立)
  3. doFilter 過濾方法
    第 3 步,每次攔截到請求,就會執行
  4. destroy 銷燬
    第 4 步,停止 web 工程的時候,就會執行(停止 web 工程,也會銷燬 Filter 過濾器)

FilterConfig(Filter過濾器設定類)

Tomcat 每次建立 Filter 的時候,也會同時建立一個 FilterConfig 類,這裡包含了 Filter 組態檔的設定資訊。

FilterConfig 類的作用是獲取 filter 過濾器的設定內容:

  1. 獲取 Filter 的名稱 filter-name 的內容
  2. 獲取在 Filter 中設定的 init-param 初始化引數
  3. 獲取 ServletContext 物件

FilterChain 過濾器鏈

在多個Filter執行的時候,它們執行的優先順序由它們在web.xml中從上到下設定的順序決定!!!

過濾器鏈(多個Filter執行)的特點:

  1. 所有filter和目標資源預設都執行在一個執行緒中。
  2. 多個filter共同執行的時候,它們使用的是同一個Request物件。

Filter 的3種攔截路徑匹配規則:

  • 精確匹配 /target.jsp
  • 目錄匹配 /admin/*
  • 字尾名匹配 *.html
    Filter 過濾器它只關心請求的地址是否匹配,不關心請求的資源是否存在!!!

Listener

用於對其他物件身上發生的事件或狀態改變進行監聽和相應處理的物件,當被監視的物件發生情況時,立即採取相應的行動。本質是觀察者模式
Servlet監聽器:Servlet規範中定義的一種特殊類,它用於監聽Web應用程式中的ServletContext,HttpSession 和HttpServletRequest等域物件的建立與銷燬事件,以及監聽這些域物件中的屬性發生修改的事件。

監聽器分為3類

  • 域物件監聽器
  • 域物件的屬性域監聽器
  • Session域中資料的監聽器

八大監聽器

  1. ServletContextListener
    監聽ServletContext物件的建立與銷燬

在SpringMVC中,有個ContextLoaderListener,這個監聽器就實現了ServletContextListener介面,表示對ServletContext物件本身的生命週期進行監控
2. HttpSessionListener
監聽HttpSession物件的建立與銷燬
3. ServletRequestListener
監聽ServletRequest物件的建立與銷燬
4. ServletContextAttributeListener
監聽ServletContext中屬性的建立、修改和銷燬
5. HttpSessionAttributeListener
監聽HttpSession中屬性的建立、修改和銷燬
6. ServletRequestAttributeListener
監聽ServletRequest中屬性的建立、修改和銷燬
7. HttpSessionBindingListener
監聽某個物件在Session域中的建立與移除
8. HttpSessionActivationListener
監聽某個物件在Session中的序列化與反序列化。

Listener 監聽器的使用步驟:

  1. 實現八大監聽器中相應一種,重寫相應的方法
  2. 到 web.xml 中去設定 Listener

web.xml 中的設定:

<listener>
    <listener-class>com.demo.listener.AtguiguListener</listener-class>
</listener>