HTTP協(xié)議是JavaWeb開發(fā)的核心基礎(chǔ),Servlet/JSP的本質(zhì)就是按照HTTP協(xié)議規(guī)范,處理客戶端的HTTP請求、生成HTTP響應(yīng)。掌握HTTP協(xié)議,是理解Web交互邏輯、排查Web程序報錯的核心前提,也是后續(xù)學習Servlet、Cookie/Session的必備基礎(chǔ)。
1 HTTP協(xié)議簡介
1.1 核心定義
HTTP(HyperText Transfer Protocol,超文本傳輸協(xié)議)是應(yīng)用層的標準化通信協(xié)議,規(guī)范了瀏覽器(客戶端)與Web服務(wù)器(Servlet容器,如Tomcat)之間的通信規(guī)則,核心是約定了客戶端與服務(wù)端之間傳輸數(shù)據(jù)的格式(即HTTP報文格式)。
其中,客戶端發(fā)送給服務(wù)器的稱為請求報文,服務(wù)器返回給客戶端的稱為響應(yīng)報文。
1.2 發(fā)展歷程(JavaWeb開發(fā)核心關(guān)注HTTP/1.1)
HTTP/0.9(1991):HTTP原型版本,僅支持GET請求,僅能傳輸HTML文本,已完全淘汰。
HTTP/1.0(1996):新增POST、HEAD請求方法,支持請求/響應(yīng)頭、多類型內(nèi)容傳輸;核心缺陷是每次請求都需新建TCP連接,性能低下。
HTTP/1.1(1997,RFC 2616,JavaWeb開發(fā)主流標準):
是Tomcat等Servlet容器默認支持的核心版本,核心改進如下:
持久連接(keep-alive):單個TCP連接可處理多個HTTP請求/響應(yīng),大幅降低連接開銷;
虛擬主機支持:單IP可部署多個Web應(yīng)用,對應(yīng)Tomcat的Host配置;
完善的緩存控制機制;
新增OPTIONS、PUT、DELETE等標準請求方法,適配后續(xù)RESTful開發(fā)。
HTTP/2(2015):基于二進制幀,支持多路復用、頭部壓縮,性能大幅優(yōu)化,Servlet 4.0+規(guī)范已兼容。
HTTP/3(2021):基于QUIC協(xié)議(UDP傳輸),進一步降低延遲、提升可靠性,主流云廠商與瀏覽器已支持。
1.3 HTTP協(xié)議核心特性(JavaWeb開發(fā)必須掌握)
這部分是后續(xù)Servlet、Cookie/Session技術(shù)的前置理論,為核心重點:
請求-響應(yīng)模型:一次完整的HTTP通信,必須由客戶端主動發(fā)起請求,服務(wù)器接收后處理并返回響應(yīng),無請求則無響應(yīng)。
無連接特性:HTTP/1.0默認每次請求新建連接,處理完成立即斷開;HTTP/1.1默認開啟持久連接,可配置連接超時時間。
無狀態(tài)特性:協(xié)議本身不記錄客戶端的歷史請求信息,每次請求都是完全獨立的。這是JavaWeb中Cookie、Session技術(shù)的核心設(shè)計背景——用于解決HTTP無狀態(tài)帶來的會話保持問題。
1.4 HTTP通信完整流程
簡化為4個核心步驟,貼合Tomcat與JavaWeb的實際運行邏輯:
建立TCP連接:客戶端根據(jù)URL的IP+端口,與服務(wù)器(Tomcat)建立TCP連接(HTTP默認端口80,Tomcat默認端口8080);
發(fā)送請求報文:客戶端按照HTTP規(guī)范,向服務(wù)器發(fā)送請求報文;
處理請求并返回響應(yīng):Tomcat接收請求,交由對應(yīng)Servlet處理業(yè)務(wù)邏輯,生成并返回響應(yīng)報文;
關(guān)閉/復用連接:HTTP/1.1默認復用持久連接,超時后自動斷開。
3.1.5 調(diào)試工具:瀏覽器F12開發(fā)者工具
所有主流瀏覽器均支持F12開發(fā)者工具,其中【網(wǎng)絡(luò)(Network)】面板是JavaWeb開發(fā)調(diào)試的核心工具,可抓取、查看完整的請求/響應(yīng)報文、狀態(tài)碼、請求參數(shù)、響應(yīng)內(nèi)容等。
例如:訪問http://localhost:8080/05_web_tomcat/login.html出現(xiàn)“URL拼寫可能存在錯誤”報錯時,可通過該面板查看請求URL是否正確、響應(yīng)狀態(tài)碼是否為404,快速定位問題。
2 HTTP請求與響應(yīng)報文(核心重點,對應(yīng)Servlet API)
【前置說明】JavaWeb中,HttpServletRequest對象就是對HTTP請求報文的完整封裝,HttpServletResponse對象就是對HTTP響應(yīng)報文的完整封裝。掌握報文結(jié)構(gòu),就能直接理解Servlet中對應(yīng)API的設(shè)計邏輯。
2.1 報文通用結(jié)構(gòu)
HTTP報文分為報文首部和報文主體,兩者通過一個空行分隔:
報文首部:包含請求/響應(yīng)的控制信息,分為「行」和「頭」兩部分;
報文主體:傳輸?shù)臉I(yè)務(wù)數(shù)據(jù)(如表單參數(shù)、HTML頁面、JSON數(shù)據(jù)等)。
2.2 請求報文(客戶端→服務(wù)器,對應(yīng)HttpServletRequest)
1. 請求報文完整結(jié)構(gòu)
請求行
請求頭
空行
請求體
2. 各部分詳解(綁定Servlet對應(yīng)API)
-
① 請求行:請求報文的第一行,固定格式為
請求方式 資源路徑 協(xié)議/版本
示例:GET /05_web_tomcat/login.html HTTP/1.1
核心字段與Servlet API對應(yīng)關(guān)系:
請求方式:
request.getMethod()資源路徑:
request.getRequestURI()/request.getRequestURL()協(xié)議版本:
request.getProtocol()② 請求頭:鍵值對格式,攜帶客戶端環(huán)境信息、請求配置等,每行一個頭信息
僅保留JavaWeb開發(fā)高頻使用的請求頭,如下表:
| 請求頭 | 核心含義 | 對應(yīng)Servlet API |
|---|---|---|
| Host | 請求的服務(wù)器域名/IP+端口 |
request.getServerName() / request.getServerPort()
|
| Connection | 連接控制(keep-alive/close) | request.getHeader("Connection") |
| Content-Type | 請求體的數(shù)據(jù)類型(POST請求必填) | request.getContentType() |
| Content-Length | 請求體的字節(jié)長度 | request.getContentLength() |
| Referer | 請求的來源頁面地址(防盜鏈、跳轉(zhuǎn)回退) | request.getHeader("Referer") |
| User-Agent | 客戶端(瀏覽器)的系統(tǒng)、版本信息 | request.getHeader("User-Agent") |
| Cookie | 客戶端攜帶的Cookie數(shù)據(jù) | request.getCookies() |
③ 空行:分隔請求頭與請求體,標識請求頭傳輸結(jié)束
④ 請求體:僅POST/PUT等請求存在,GET請求無請求體;用于傳輸客戶端提交的業(yè)務(wù)數(shù)據(jù)(如表單參數(shù)、文件、JSON等)
對應(yīng)Servlet API:request.getInputStream() / request.getReader() / request.getParameter()
3. 核心請求方式:GET與POST(JavaWeb開發(fā)最常用,表單提交核心)
| 特性 | GET請求 | POST請求 |
|---|---|---|
| 參數(shù)位置 | 拼接在URL后,格式為url?name1=value1&name2=value2,地址欄可見 |
放在請求體中,地址欄不可見 |
| 安全性 | 低,參數(shù)直接暴露,不可傳輸敏感數(shù)據(jù) | 相對更高,參數(shù)不直接暴露 |
| 數(shù)據(jù)限制 | 受瀏覽器地址欄長度限制(一般約4KB),僅能傳輸文本 | 無長度限制,支持文本、二進制文件等 |
| 請求體 | 無請求體 | 有請求體,需配合Content-Type指定數(shù)據(jù)格式 |
| 緩存特性 | 瀏覽器默認會緩存 | 瀏覽器默認不緩存 |
| 開發(fā)場景 | 頁面跳轉(zhuǎn)、數(shù)據(jù)查詢、無敏感信息的簡單參數(shù)傳遞 | 表單提交、文件上傳、敏感數(shù)據(jù)傳輸、數(shù)據(jù)增刪改操作 |
提示:HTML表單默認提交方式為GET,需手動設(shè)置method="post"才會使用POST請求;Servlet中需通過doGet()/doPost()方法分別處理對應(yīng)請求,方法不匹配會拋出405狀態(tài)碼錯誤。
2.3 響應(yīng)報文(服務(wù)器→客戶端,對應(yīng)HttpServletResponse)
1. 響應(yīng)報文完整結(jié)構(gòu)
響應(yīng)行
響應(yīng)頭
空行
響應(yīng)體
2. 各部分詳解(綁定Servlet對應(yīng)API)
-
① 響應(yīng)行:響應(yīng)報文的第一行,固定格式為
協(xié)議/版本 狀態(tài)碼 狀態(tài)描述
示例:HTTP/1.1 200 OK
核心字段與Servlet API對應(yīng)關(guān)系:
狀態(tài)碼:
response.setStatus(int sc)協(xié)議版本:由Servlet容器自動設(shè)置,可通過
response.getProtocol()獲取② 響應(yīng)頭:鍵值對格式,攜帶服務(wù)器的響應(yīng)配置、數(shù)據(jù)信息等,每行一個頭信息
僅保留JavaWeb開發(fā)高頻使用的響應(yīng)頭,如下表:
| 響應(yīng)頭 | 核心含義 | 對應(yīng)Servlet API |
|---|---|---|
| Content-Type | 響應(yīng)體的數(shù)據(jù)類型與編碼(瀏覽器據(jù)此解析內(nèi)容) | response.setContentType() |
| Content-Length | 響應(yīng)體的字節(jié)長度 | response.setContentLength() |
| Location | 重定向的目標地址(配合302狀態(tài)碼使用) |
response.sendRedirect() 底層依賴此頭 |
| Set-Cookie | 服務(wù)器向客戶端寫入Cookie | response.addCookie() |
| Cache-Control | 緩存控制策略 | response.setHeader("Cache-Control", "...") |
| Server | 服務(wù)器信息(如Tomcat版本) | 由Servlet容器自動設(shè)置 |
③ 空行:分隔響應(yīng)頭與響應(yīng)體,標識響應(yīng)頭傳輸結(jié)束
④ 響應(yīng)體:服務(wù)器返回的核心數(shù)據(jù),瀏覽器會根據(jù)Content-Type解析渲染,如HTML頁面、圖片、JSON、文件等
對應(yīng)Servlet API:response.getOutputStream() / response.getWriter()
3. 核心響應(yīng)狀態(tài)碼(JavaWeb開發(fā)高頻必掌握)
HTTP狀態(tài)碼為3位數(shù)字,首位代表響應(yīng)類別,高頻核心狀態(tài)碼如下:
| 狀態(tài)碼 | 核心含義 | 開發(fā)場景說明 |
|---|---|---|
| 200 OK | 請求成功 | 正常訪問頁面、接口成功,服務(wù)器已正常返回數(shù)據(jù) |
| 302 Found | 臨時重定向 | Servlet中response.sendRedirect()的默認狀態(tài)碼,服務(wù)器要求客戶端發(fā)起新的請求 |
| 304 Not Modified | 資源未修改 | 客戶端使用本地緩存的資源,服務(wù)器未返回新內(nèi)容 |
| 400 Bad Request | 請求語法錯誤 | 請求參數(shù)格式錯誤、請求體格式異常,服務(wù)器無法解析 |
| 404 Not Found | 請求資源不存在 | 最常見報錯之一,如URL拼寫錯誤、項目未部署、資源路徑錯誤、Servlet路徑配置錯誤,對應(yīng)本次案例中“URL拼寫可能存在錯誤”的報錯 |
| 405 Method Not Allowed | 請求方法不允許 | Servlet中未實現(xiàn)對應(yīng)請求方法(如表單用POST提交,但Servlet僅重寫了doGet()) |
| 500 Internal Server Error | 服務(wù)器內(nèi)部錯誤 | 服務(wù)器端代碼運行異常,如Servlet中拋出空指針、SQL異常等,是后端代碼報錯的核心標識 |
提示:其他狀態(tài)碼可在開發(fā)中按需查閱,入門階段優(yōu)先掌握以上高頻狀態(tài)碼,即可解決絕大多數(shù)Web程序調(diào)試問題。
【本章與后續(xù)JavaWeb內(nèi)容的銜接】
后續(xù)學習的Servlet,本質(zhì)就是Tomcat完成以下流程:
接收客戶端的HTTP請求報文,封裝為
HttpServletRequest對象;根據(jù)請求路徑,調(diào)用對應(yīng)Servlet的
doGet()/doPost()方法處理業(yè)務(wù)邏輯;開發(fā)者通過
HttpServletResponse對象,封裝生成符合HTTP規(guī)范的響應(yīng)報文,由Tomcat返回給客戶端。
(注: )