JavaWeb之Request與Response詳解
HTTP協議
簡介
HTTP 作業原理
請求訊息資料格式
1. 請求行
2. 請求頭
3. 請求空行
4. 請求體(正文)
回應訊息資料格式
1. 回應行:
2. 回應頭:
3. 回應空行
4. 回應體:傳輸的資料
請求:request
請求轉發:一種在服務器內部的資源跳轉方式
共享資料
回應:response物件
重定向
ServletContext物件:
1. 概念:
2. 獲取:
3. 功能:
檔案下載小例子
前端代碼
后端代碼
HTTP協議
簡介
HTTP協議(HyperText Transfer Protocol,超文本傳輸協議)是因特網上應用最為廣泛的一種網路傳輸協議,所有的WWW檔案都必須遵守這個標準,
HTTP是一個基于TCP/IP通信協議來傳遞資料(HTML 檔案, 圖片檔案, 查詢結果等),
HTTP 作業原理
HTTP協議作業于客戶端-服務端架構上,瀏覽器作為HTTP客戶端通過URL向HTTP服務端即WEB服務器發送所有請求,
Web服務器有:Apache服務器,IIS服務器(Internet Information Services)等,
Web服務器根據接收到的請求后,向客戶端發送回應資訊,
HTTP默認埠號為80,但是你也可以改為8080或者其他埠,
HTTP三點注意事項:
- HTTP是無連接:無連接的含義是限制每次連接只處理一個請求,服務器處理完客戶的請求,并收到客戶的應答后,即斷開連接,采用這種方式可以節省傳輸時間,
- HTTP是媒體獨立的:這意味著,只要客戶端和服務器知道如何處理的資料內容,任何型別的資料都可以通過HTTP發送,客戶端以及服務器指定使用適合的MIME-type內容型別,
- HTTP是無狀態:HTTP協議是無狀態協議,無狀態是指協議對于事務處理沒有記憶能力,缺少狀態意味著如果后續處理需要前面的資訊,則它必須重傳,這樣可能導致每次連接傳送的資料量增大,另一方面,在服務器不需要先前資訊時它的應答就較快,
- 瀏覽器顯示的內容都有 HTML、XML、GIF、Flash 等,瀏覽器是通過 MIME Type 區分它們,決定用什么內容什么形式來顯示,
請求訊息資料格式
客戶端發送一個HTTP請求到服務器的請求訊息包括以下格式:請求行(request line)、請求頭部(header)、空行和請求資料四個部分組成,下圖給出了請求報文的一般格式,

1. 請求行
請求行中的“方法”實際上就是命令,表示客戶端希望服務器對URL指定的資源執行的操作(或動作),即表示服務器做什么;URL定位所請求的資源;協議版本用于通告服務器客戶端所使用的HTTP版本號,

常見的請求方式有兩種:
GET:
1. 請求引數在請求行中,在url后,
2. 請求的url長度有限制的
3. 不太安全
POST:
1. 請求引數在請求體中
2. 請求的url長度沒有限制的
3. 相對安全
2. 請求頭
HTTP報文的首部行用于攜帶附加資訊,可以有零行、一行或者多行,每個首部行包括一個首部行欄位名,后面跟一個冒號,然后是一個可選的空格,緊接著是對應的值,最后是CRLF,
不同首部行攜帶不用類別資訊,用于不同目的,
| 頭資訊 | 描述 |
|---|---|
| Accept | 這個頭資訊指定瀏覽器或其他客戶端可以處理的 MIME 型別,值 image/png 或 image/jpeg 是最常見的兩種可能值, |
| Accept-Charset | 這個頭資訊指定瀏覽器可以用來顯示資訊的字符集,例如 ISO-8859-1, |
| Accept-Encoding | 這個頭資訊指定瀏覽器知道如何處理的編碼型別,值 gzip 或 compress 是最常見的兩種可能值, |
| Accept-Language | 這個頭資訊指定客戶端的首選語言,在這種情況下,Servlet 會產生多種語言的結果,例如,en、en-us、ru 等, |
| Authorization | 這個頭資訊用于客戶端在訪問受密碼保護的網頁時識別自己的身份, |
| Connection | 這個頭資訊指示客戶端是否可以處理持久 HTTP 連接,持久連接允許客戶端或其他瀏覽器通過單個請求來檢索多個檔案,值 Keep-Alive 意味著使用了持續連接, |
| Content-Length | 這個頭資訊只適用于 POST 請求,并給出 POST 資料的大小(以位元組為單位), |
| Cookie | 這個頭資訊把之前發送到瀏覽器的 cookies 回傳到服務器, |
| Host | 這個頭資訊指定原始的 URL 中的主機和埠, |
| If-Modified-Since | 這個頭資訊表示只有當頁面在指定的日期后已更改時,客戶端想要的頁面,如果沒有新的結果可以使用,服務器會發送一個 304 代碼,表示 Not Modified 頭資訊, |
| If-Unmodified-Since | 這個頭資訊是 If-Modified-Since 的對立面,它指定只有當檔案早于指定日期時,操作才會成功, |
| Referer | 這個頭資訊指示所指向的 Web 頁的 URL,例如,如果您在網頁 1,點擊一個鏈接到網頁 2,當瀏覽器請求網頁 2 時,網頁 1 的 URL 就會包含在 Referer 頭資訊中, |
| User-Agent | 這個頭資訊識別發出請求的瀏覽器或其他客戶端,并可以向不同型別的瀏覽器回傳不同的內容, |
3. 請求空行
空行,用于分隔請求行與請求資料
4. 請求體(正文)
封裝POST請求訊息的請求引數的
請求體,是請求報文的負荷,可以是文本、圖片、視頻、HTML 檔案、應用程式、電子郵件等,
回應訊息資料格式
回應資訊由Web服務器發送給瀏覽器,HTTP回應也由四個部分組成,分別是:狀態行、訊息報頭、空行和回應正文,


1. 回應行:
1. 組成:協議/版本 回應狀態碼 狀態碼描述
2. 回應狀態碼:服務器告訴客戶端瀏覽器本次請求和回應的一個狀態,不同狀態具有不同含義
1. 狀態碼都是3位數字
2. 分類:
| 分類 | 分類描述 |
|---|---|
| 1** | 資訊,服務器收到請求,需要請求者繼續執行操作 |
| 2** | 成功,操作被成功接收并處理,代表:200 |
| 3** | 重定向,需要進一步的操作以完成請求,代表:302(重定向),304(訪問緩沖) |
| 4** | 客戶端錯誤,請求包含語法錯誤或無法完成請求,代表:404(請求路徑沒有對應的資源),405(請求方式沒有對應的doXxx方法) |
| 5** | 服務器錯誤,服務器在處理請求的程序中發生了錯誤,代表:500(服務器內部出現例外) |
2. 回應頭:
| 頭資訊 | 描述 |
|---|---|
| Allow | 這個頭資訊指定服務器支持的請求方法(GET、POST 等), |
| Cache-Control | 這個頭資訊指定回應檔案在何種情況下可以安全地快取,可能的值有:public、private 或 no-cache 等,Public 意味著檔案是可快取,Private 意味著檔案是單個用戶私用檔案,且只能存盤在私有(非共享)快取中,no-cache 意味著檔案不應被快取, |
| Connection | 這個頭資訊指示瀏覽器是否使用持久 HTTP 連接,值 close 指示瀏覽器不使用持久 HTTP 連接,值 keep-alive 意味著使用持久連接, |
| Content-Disposition | 這個頭資訊可以讓您請求瀏覽器要求用戶以給定名稱的檔案把回應保存到磁盤, |
| Content-Encoding | 在傳輸程序中,這個頭資訊指定頁面的編碼方式, |
| Content-Language | 這個頭資訊表示檔案撰寫所使用的語言,例如,en、en-us、ru 等, |
| Content-Length | 這個頭資訊指示回應中的位元組數,只有當瀏覽器使用持久(keep-alive)HTTP 連接時才需要這些資訊, |
| Content-Type | 這個頭資訊提供了回應檔案的 MIME(Multipurpose Internet Mail Extension)型別, |
| Expires | 這個頭資訊指定內容過期的時間,在這之后內容不再被快取, |
| Last-Modified | 這個頭資訊指示檔案的最后修改時間,然后,客戶端可以快取檔案,并在以后的請求中通過 If-Modified-Since 請求頭資訊提供一個日期, |
| Location | 這個頭資訊應被包含在所有的帶有狀態碼的回應中,在 300s 內,這會通知瀏覽器檔案的地址,瀏覽器會自動重新連接到這個位置,并獲取新的檔案, |
| Refresh | 這個頭資訊指定瀏覽器應該如何盡快請求更新的頁面,您可以指定頁面重繪的秒數, |
| Retry-After | 這個頭資訊可以與 503(Service Unavailable 服務不可用)回應配合使用,這會告訴客戶端多久就可以重復它的請求, |
| Set-Cookie | 這個頭資訊指定一個與頁面關聯的 cookie, |
3. 回應空行
4. 回應體:傳輸的資料
回應空行與相應體的作用與請求報文相同,
請求:request
下面的方法可用在Servlet程式中讀取HTTP頭,這些方法通過HttpServletRequest物件可用,
| 序號 | 方法 & 描述 |
|---|---|
| 1 | Cookie[] getCookies() 回傳一個陣列,包含客戶端發送該請求的所有的 Cookie 物件, |
| 2 | Enumeration getAttributeNames() 回傳一個列舉,包含提供給該請求可用的屬性名稱, |
| 3 | Enumeration getHeaderNames() 回傳一個列舉,包含在該請求中包含的所有的頭名, |
| 4 | Enumeration getParameterNames() 回傳一個 String 物件的列舉,包含在該請求中包含的引數的名稱, |
| 5 | HttpSession getSession() 回傳與該請求關聯的當前 session 會話,或者如果請求沒有 session 會話,則創建一個, |
| 6 | HttpSession getSession(boolean create) 回傳與該請求關聯的當前 HttpSession,或者如果沒有當前會話,且創建是真的,則回傳一個新的 session 會話, |
| 7 | Locale getLocale() 基于 Accept-Language 頭,回傳客戶端接受內容的首選的區域設定, |
| 8 | Object getAttribute(String name) 以物件形式回傳已命名屬性的值,如果沒有給定名稱的屬性存在,則回傳 null, |
| 9 | ServletInputStream getInputStream() 使用 ServletInputStream,以二進制資料形式檢索請求的主體, |
| 10 | String getAuthType() 回傳用于保護 Servlet 的身份驗證方案的名稱,例如,"BASIC" 或 "SSL",如果JSP沒有受到保護則回傳 null, |
| 11 | String getCharacterEncoding() 回傳請求主體中使用的字符編碼的名稱, |
| 12 | String getContentType() 回傳請求主體的 MIME 型別,如果不知道型別則回傳 null, |
| 13 | String getContextPath() 回傳指示請求背景關系的請求 URI 部分, |
| 14 | String getHeader(String name) 以字串形式回傳指定的請求頭的值, |
| 15 | String getMethod() 回傳請求的 HTTP 方法的名稱,例如,GET、POST 或 PUT, |
| 16 | String getParameter(String name) 以字串形式回傳請求引數的值,或者如果引數不存在則回傳 null, |
| 17 | String getPathInfo() 當請求發出時,回傳與客戶端發送的 URL 相關的任何額外的路徑資訊, |
| 18 | String getProtocol() 回傳請求協議的名稱和版本, |
| 19 | String getQueryString() 回傳包含在路徑后的請求 URL 中的查詢字串, |
| 20 | String getRemoteAddr() 回傳發送請求的客戶端的互聯網協議(IP)地址, |
| 21 | String getRemoteHost() 回傳發送請求的客戶端的完全限定名稱, |
| 22 | String getRemoteUser() 如果用戶已通過身份驗證,則回傳發出請求的登錄用戶,或者如果用戶未通過身份驗證,則回傳 null, |
| 23 | String getRequestURI() 從協議名稱直到 HTTP 請求的第一行的查詢字串中,回傳該請求的 URL 的一部分, |
| 24 | String getRequestedSessionId() 回傳由客戶端指定的 session 會話 ID, |
| 25 | String getServletPath() 回傳呼叫 JSP 的請求的 URL 的一部分, |
| 26 | String[] getParameterValues(String name) 回傳一個字串物件的陣列,包含所有給定的請求引數的值,如果引數不存在則回傳 null, |
| 27 | boolean isSecure() 回傳一個布林值,指示請求是否使用安全通道,如 HTTPS, |
| 28 | int getContentLength() 以位元組為單位回傳請求主體的長度,并提供輸入流,或者如果長度未知則回傳 -1, |
| 29 | int getIntHeader(String name) 回傳指定的請求頭的值為一個 int 值, |
| 30 | int getServerPort() 回傳接收到這個請求的埠號, |
| 31 | int getParameterMap() 將引數封裝成 Map 型別, |
請求轉發:一種在服務器內部的資源跳轉方式
1. 通過request物件獲取請求轉發器物件:
RequestDispatcher getRequestDispatcher(String path)
2. 使用RequestDispatcher物件來進行轉發:
forward(ServletRequest request, ServletResponse response)
轉發到另個類,需要request.getAttribute("轉發的內容的名字");
共享資料
域物件:一個有作用范圍的物件,可以在范圍內共享資料
request域:代表一次請求的范圍,一般用于請求轉發的多個資源中共享資料
方法:
1. void setAttribute(String name,Object obj):存盤資料
2. Object getAttitude(String name):通過鍵獲取值
3. void removeAttribute(String name):通過鍵移除鍵值對
回應:response物件
下面的方法可用于在 Servlet 程式中設定 HTTP 回應報頭,這些方法通過 HttpServletResponse 物件可用,
| 序號 | 方法 & 描述 |
|---|---|
| 1 | String encodeRedirectURL(String url) 為 sendRedirect 方法中使用的指定的 URL 進行編碼,或者如果編碼不是必需的,則回傳 URL 未改變, |
| 2 | String encodeURL(String url) 對包含 session 會話 ID 的指定 URL 進行編碼,或者如果編碼不是必需的,則回傳 URL 未改變, |
| 3 | boolean containsHeader(String name) 回傳一個布林值,指示是否已經設定已命名的回應報頭, |
| 4 | boolean isCommitted() 回傳一個布林值,指示回應是否已經提交, |
| 5 | void addCookie(Cookie cookie) 把指定的 cookie 添加到回應, |
| 6 | void addDateHeader(String name, long date) 添加一個帶有給定的名稱和日期值的回應報頭, |
| 7 | void addHeader(String name, String value) 添加一個帶有給定的名稱和值的回應報頭, |
| 8 | void addIntHeader(String name, int value) 添加一個帶有給定的名稱和整數值的回應報頭, |
| 9 | void flushBuffer() 強制任何在緩沖區中的內容被寫入到客戶端, |
| 10 | void reset() 清除緩沖區中存在的任何資料,包括狀態碼和頭, |
| 11 | void resetBuffer() 清除回應中基礎緩沖區的內容,不清除狀態碼和頭, |
| 12 | void sendError(int sc) 使用指定的狀態碼發送錯誤回應到客戶端,并清除緩沖區, |
| 13 | void sendError(int sc, String msg) 使用指定的狀態發送錯誤回應到客戶端, |
| 14 | void sendRedirect(String location) 使用指定的重定向位置 URL 發送臨時重定向回應到客戶端, |
| 15 | void setBufferSize(int size) 為回應主體設定首選的緩沖區大小, |
| 16 | void setCharacterEncoding(String charset) 設定被發送到客戶端的回應的字符編碼(MIME 字符集)例如,UTF-8, |
| 17 | void setContentLength(int len) 設定在 HTTP Servlet 回應中的內容主體的長度,該方法設定 HTTP Content-Length 頭, |
| 18 | void setContentType(String type) 如果回應還未被提交,設定被發送到客戶端的回應的內容型別, |
| 19 | void setDateHeader(String name, long date) 設定一個帶有給定的名稱和日期值的回應報頭, |
| 20 | void setHeader(String name, String value) 設定一個帶有給定的名稱和值的回應報頭, |
| 21 | void setIntHeader(String name, int value) 設定一個帶有給定的名稱和整數值的回應報頭, |
| 22 | void setLocale(Locale loc) 如果回應還未被提交,設定回應的區域, |
| 23 | void setStatus(int sc) 為該回應設定狀態碼, |
重定向
1. 設定狀態碼為302
response.setStatus(302);
2.設定回應頭location
response.setHeader("location","/day15/responseDemo2");
簡單的重定向方法
response.sendRedirect("/day15/responseDemo2");
亂碼問題:
response.setContentType("text/html;charset=utf-8");
ServletContext物件:
1. 概念:
代表整個web應用,可以和程式的容器(服務器)來通信
2. 獲取:
1. 通過request物件獲取
request.getServletContext();
2. 通過HttpServlet獲取
this.getServletContext();
3. 功能:
1. 獲取MIME型別:
MIME型別:在互聯網通信程序中定義的一種檔案資料型別
格式: 大型別/小型別 text/html image/jpeg
獲取:String getMimeType(String file)
2. 域物件:共享資料
1. setAttribute(String name,Object value)
2. getAttribute(String name)
3. removeAttribute(String name)
ServletContext物件范圍:所有用戶所有請求的資料
3. 獲取檔案的真實(服務器)路徑
1. 方法:String getRealPath(String path)
String b = context.getRealPath("/b.txt");//web目錄下資源訪問
String c = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目錄下的資源訪
String a = context.getRealPath("/WEB-INF/classes/a.txt");//src目錄下的資源訪問
檔案下載小例子
前端代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- 加上虛擬目錄-->
<a href="/JavaEE_Web_02_01code_war_exploded/img/女.jpg">展示圖片</a>
<a href="/JavaEE_Web_02_01code_war_exploded/DownloadServlet?filename=img/女.jpg ">下載圖片</a>
<a href="/JavaEE_Web_02_01code_war_exploded/img/女.png">展示圖片</a>
<a href="/JavaEE_Web_02_01code_war_exploded/DownloadServlet?filename=img/女.png">下載圖片</a>
</body>
</html>
后端代碼
package com.example.JavaEE_Web_02_01code.ServletContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ResourceBundle;
/**
* @Author: Promsing
* @Date: 2021/2/2 - 19:41
* @Description: 檔案下載
* @version: 1.0
*/
@WebServlet("/DownloadServlet")
public class DownloadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.獲取請求引數,檔案名稱
String filename = request.getParameter("filename");
//2.使用位元組輸入流加載檔案到記憶體
ServletContext servletContext = this.getServletContext();
String realPath = servletContext.getRealPath(filename);
FileInputStream fis=new FileInputStream(realPath);
//注意:設定response的回應頭
String mimeType = servletContext.getMimeType(filename);
response.setHeader("content-type",mimeType);
response.setHeader("content-disposition","attachment;filename"+filename);
//3.將輸入流的資料寫道輸出流中
ServletOutputStream sos = response.getOutputStream();
byte[] bytes=new byte[1024*8];
int len=0;
while ((len=fis.read(bytes))!=-1){
sos.write(bytes,0,len);
}
//管理流
fis.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
創作不易,如果本篇博客對您有一定的幫助,大家記得留言+點贊哦,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/262598.html
標籤:其他
下一篇:Java 開發工程師的核心競爭力
