javaweb 上篇
一、Tomcat 核心定位與職責(zé)
1. Tomcat 是什么?
Tomcat 是 Web 服務(wù)器(Servlet 容器),核心作用是:
- 服務(wù)初始化:啟動時加載 Web 應(yīng)用配置(如
web.xml
),創(chuàng)建ServletContext
(應(yīng)用域)和ServletConfig
(Servlet 配置)。 - 網(wǎng)絡(luò)通信:監(jiān)聽端口(默認(rèn) 8080),接收客戶端 HTTP 請求。
- 請求處理:解析請求路徑,通過「路由規(guī)則」將請求分發(fā)到對應(yīng)的 Servlet 處理,并返回響應(yīng)。
2. Tomcat 與 Servlet 的關(guān)系
Tomcat 是 Servlet 規(guī)范的實現(xiàn)者,負(fù)責(zé):
- 解析配置:讀取
web.xml
或注解配置,創(chuàng)建ServletConfig
對象(每個 Servlet 一個),存儲初始化參數(shù)(如數(shù)據(jù)庫連接信息)。 - 生命周期管理:控制 Servlet 的
init()
、service()
、destroy()
方法調(diào)用,無需開發(fā)者手動管理。
二、Servlet 規(guī)范與實現(xiàn)類
1. Servlet 接口(規(guī)范)
- 地位:Java EE 定義的接口(
jakarta.servlet.Servlet
),規(guī)定了 Servlet 的核心方法(如init
、service
、destroy
)。 - 作用:開發(fā)者需實現(xiàn)此接口或繼承其子類,定義具體的業(yè)務(wù)邏輯(如處理登錄、數(shù)據(jù)查詢)。
2. Servlet 實現(xiàn)類的繼承層次
jakarta.servlet.Servlet(接口) // 爺爺:定義通用方法
├─ jakarta.servlet.GenericServlet(抽象類) // 兒子:實現(xiàn)通用邏輯(非 HTTP 專用)
│ ├─ jakarta.servlet.http.HttpServlet(抽象類) // 孫子:HTTP 協(xié)議專用,簡化開發(fā)
GenericServlet
:- 實現(xiàn)
Servlet
接口,提供ServletConfig
封裝(通過getServletConfig()
獲取配置)。 - 適用于非 HTTP 協(xié)議(如 FTP),但實際開發(fā)中較少直接使用。
- 實現(xiàn)
HttpServlet
(重點?。?- 繼承
GenericServlet
,專為 HTTP 協(xié)議設(shè)計,提供doGet
、doPost
、doDelete
等方法,直接處理不同類型的 HTTP 請求。 - 示例:
@WebServlet("/user") public class UserServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) { // 處理 GET 請求(如查詢用戶) } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) { // 處理 POST 請求(如創(chuàng)建用戶) } }
- 繼承
三、ServletConfig:單個 Servlet 的配置容器
1. 作用
- 每個 Servlet 對應(yīng)一個
ServletConfig
對象,存儲 當(dāng)前 Servlet 的初始化參數(shù)(如該 Servlet 獨有的配置項)。 - 提供方法訪問配置信息:
String getInitParameter(String name); // 通過參數(shù)名獲取值(如數(shù)據(jù)庫 URL) Enumeration<String> getInitParameterNames(); // 獲取所有參數(shù)名 ServletContext getServletContext(); // 獲取當(dāng)前 Web 應(yīng)用的上下文(應(yīng)用域)
2. 配置方式
web.xml
配置:<servlet> <servlet-name>userServlet</servlet-name> <servlet-class>com.example.UserServlet</servlet-class> <init-param> <param-name>dbUrl</param-name> <param-value>jdbc:mysql://localhost:3306/db</param-value> </init-param> </servlet>
- 注解配置(Servlet 3.0+):
@WebServlet( name = "userServlet", urlPatterns = "/user", initParams = @WebInitParam(name = "dbUrl", value = "jdbc:mysql://localhost:3306/db") )
四、ServletContext:Web 應(yīng)用的全局上下文(應(yīng)用域)
1. 核心特性
- 唯一性:每個 Web 應(yīng)用(部署在 Tomcat 中的一個項目)對應(yīng)一個
ServletContext
對象,所有 Servlet 共享此對象。 - 生命周期:與 Web 應(yīng)用一致(服務(wù)器啟動時創(chuàng)建,關(guān)閉時銷毀)。
- 作用:
- 共享數(shù)據(jù):存儲所有用戶共享、極少修改、數(shù)據(jù)量小的信息(如全局配置、緩存數(shù)據(jù))。
- 訪問資源:獲取 Web 應(yīng)用路徑(
getRealPath
)、讀取配置文件(getResourceAsStream
)。 - 日志記錄:通過
log(String message)
記錄應(yīng)用級日志。
2. 數(shù)據(jù)操作方法
// 存:向應(yīng)用域中存儲數(shù)據(jù)(類似 Map)
setAttribute(String name, Object value);
// ?。簭膽?yīng)用域中獲取數(shù)據(jù)
Object getAttribute(String name);
// 刪:移除應(yīng)用域中的數(shù)據(jù)
removeAttribute(String name);
示例:
// 在某個 Servlet 中存儲全局用戶信息(假設(shè)所有用戶可見)
User globalUser = new User("admin", "admin");
request.getServletContext().setAttribute("globalUser", globalUser);
// 另一個 Servlet 中獲取該數(shù)據(jù)
User user = (User) request.getServletContext().getAttribute("globalUser");
3. 注意事項
- 線程安全:數(shù)據(jù)被所有用戶共享,修改時需加鎖(如
synchronized
),避免并發(fā)問題。 - 數(shù)據(jù)量:僅存儲輕量數(shù)據(jù)(如配置項、統(tǒng)計計數(shù)器),避免大對象占用內(nèi)存。
- 用途場景:適合存儲「只讀或極少修改的全局?jǐn)?shù)據(jù)」(如系統(tǒng)版本號、公共參數(shù))。
五、總結(jié):Tomcat 與 Servlet 組件協(xié)作流程
- Tomcat 啟動:
- 解析
web.xml
或注解,創(chuàng)建ServletContext
(應(yīng)用域)和各ServletConfig
(Servlet 配置)。
- 解析
- 請求到達(dá):
- Tomcat 接收 HTTP 請求,根據(jù) URL 找到對應(yīng)的 Servlet(通過
web.xml
或@WebServlet
映射)。
- Tomcat 接收 HTTP 請求,根據(jù) URL 找到對應(yīng)的 Servlet(通過
- Servlet 處理:
- Tomcat 調(diào)用 Servlet 的
service()
方法(HttpServlet 會根據(jù)請求方法調(diào)用doGet
/doPost
等)。 - Servlet 通過
this.getServletConfig()
獲取自身配置,通過getServletContext()
訪問應(yīng)用域數(shù)據(jù)。
- Tomcat 調(diào)用 Servlet 的
- 響應(yīng)返回:
- Servlet 生成響應(yīng)數(shù)據(jù),Tomcat 將其封裝為 HTTP 響應(yīng),返回給客戶端。
通過這種分層協(xié)作,Tomcat 實現(xiàn)了「請求接收→路由分發(fā)→Servlet 處理」的完整流程,而開發(fā)者只需專注于 Servlet 業(yè)務(wù)邏輯和配置,大幅簡化 Web 應(yīng)用開發(fā)。
Javaweb 文章被收錄于專欄
JavaWeb 是指使用 Java 技術(shù)來開發(fā)基于 Web 的應(yīng)用程序,它結(jié)合了 Java 語言的強(qiáng)大功能和 Web 技術(shù)的靈活性,廣泛應(yīng)用于各種企業(yè)級 Web 應(yīng)用開發(fā)中。