前言
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個任務:
- 接收請求:將客戶端傳送過來的請求封裝成ServletRequest物件(包含請求頭、引數等各種資訊)
- 處理請求:在service方法中接收引數,並且進行處理請求。
- 資料響應:請求處理完成後,透過轉發(forward)或者重定向(redirect)到某個頁面。
轉發(forward)或者重定向(redirect)的區別? 本質:forward是HttpServletRequest的方法,redirect是HttpServletResponse的方法。 現象及結果: 1. forward客戶端只發了一次請求,在服務端進行轉發行為,可以共享資料(request中引數),瀏覽器URL不改變。 2. redirect是服務端向客戶端完成響應後,客戶端再次發起一個請求,不可以共享資料(request中引數),請求了兩次,瀏覽器URL改變。
Servlet的生命週期
-
執行 Servlet 構造器方法
第一步,在web.xml中的servlet中配置 load-on-startup 的值 ≥ 0 時,表示應用啟動時就建立這個servlet。否則,第一次訪問的時候呼叫。 -
執行 init 初始化方法
第二步,第一次訪問的時候呼叫。 -
執行 service 方法
第三步,每次訪問都會呼叫。 -
執行 destroy 銷燬方法
第四步,在 web 工程停止的時候呼叫。
透過實現 Servlet 介面 實現Servlet程式
- 實現Servlet介面,重寫service方法,處理請求,並響應資料
- 在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程式(推薦,一般開發中使用這種方式)
- 繼承 HttpServlet類,按業務需求重寫doGet 或 doPost 方法,處理請求
- 到 web.xml 中的配置 Servlet 程式的訪問地址
程式碼比實現Servlet介面的方式更加簡單,不需要進行請求的型別轉換,配置與實現Servlet介面的方式一樣,所以這裡不做演示
ServletConfig(Servlet程式的配置資訊類)
在Servlet 程式建立時,就會建立一個對應的 ServletConfig 物件。
它的三大作用:
- 獲取web.xml 中 Servlet 程式的別名 servlet-name 的值
- 獲取web.xml 中 Servlet 程式的獲取初始化引數 init-param
- 獲取 ServletContext 物件
ServletContext (Servlet上下文) 介面
- 每個web專案只有一個ServletContext物件,在web工程部署啟動的時候建立,在工程停止的時候關閉。
- ServletContext 物件是一個域物件(可以像Map一樣儲存資料的物件。域指的是作用域,這裡是整個web工程)。
ServletContext 類的四個作用:
- 獲取 web.xml 中配置的上下文引數 context-param
- getContextPath()獲取當前的工程路徑,格式: /工程路徑
- getRealPath()獲取工程部署後在伺服器硬碟上的絕對路徑
- 像 Map 一樣存取資料
HttpServletRequest 和 HttpServletResponse
HttpServletRequest
HttpServletRequest繼承了ServletRequest,每次請求進入tomcat伺服器,tomcat容器就會把請求過來的 HTTP 協議資訊解析好封裝到 Request 物件中。然後傳遞到 service 方法(doGet 和 doPost)中給我們使用。我們可以透過 HttpServletRequest 物件,獲取到所有請求的資訊
HttpServletResponse
HttpServletResponse 類和 HttpServletRequest 類一樣。每次請求進來,Tomcat 伺服器都會建立一個 Response 物件傳遞給 Servlet 程式去使用。透過 HttpServletResponsee 物件來進行設定返回給客戶端的資訊
解決請求的中文亂碼
- Get請求:獲取請求引數,先以 iso8859-1 進行編碼,再以 utf-8 進行解
- 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 的生命週期
- 構造器方法
- init 初始化方法
第 1,2 步,在 web 工程啟動的時候執行(Filter 已經建立) - doFilter 過濾方法
第 3 步,每次攔截到請求,就會執行 - destroy 銷燬
第 4 步,停止 web 工程的時候,就會執行(停止 web 工程,也會銷燬 Filter 過濾器)
FilterConfig(Filter過濾器配置類)
Tomcat 每次建立 Filter 的時候,也會同時建立一個 FilterConfig 類,這裡包含了 Filter 配置檔案的配置資訊。
FilterConfig 類的作用是獲取 filter 過濾器的配置內容:
- 獲取 Filter 的名稱 filter-name 的內容
- 獲取在 Filter 中配置的 init-param 初始化引數
- 獲取 ServletContext 物件
FilterChain 過濾器鏈
在多個Filter執行的時候,它們執行的優先順序由它們在web.xml中從上到下配置的順序決定!!!
過濾器鏈(多個Filter執行)的特點:
- 所有filter和目標資源預設都執行在一個執行緒中。
- 多個filter共同執行的時候,它們使用的是同一個Request物件。
Filter 的3種攔截路徑匹配規則:
- 精確匹配
/target.jsp - 目錄匹配
/admin/* - 字尾名匹配
*.html
Filter 過濾器它只關心請求的地址是否匹配,不關心請求的資源是否存在!!!
Listener
用於對其他物件身上發生的事件或狀態改變進行監聽和相應處理的物件,當被監視的物件發生情況時,立即採取相應的行動。本質是觀察者模式。
Servlet監聽器:Servlet規範中定義的一種特殊類,它用於監聽Web應用程式中的ServletContext,HttpSession 和HttpServletRequest等域物件的建立與銷燬事件,以及監聽這些域物件中的屬性發生修改的事件。
監聽器分為3類
- 域物件監聽器
- 域物件的屬性域監聽器
- Session域中資料的監聽器
八大監聽器
- 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 監聽器的使用步驟:
- 實現八大監聽器中相應一種,重寫相應的方法
- 到 web.xml 中去配置 Listener
web.xml 中的配置:
<listener>
<listener-class>com.demo.listener.AtguiguListener</listener-class>
</listener>