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請求頭(Header)參數詳解:https://www.cnblogs.com/lspbk/p/14431188.html
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目錄下的資源訪問
文件下載小例子
1、前端代碼
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <!-- 加上虛擬目錄--> 9 <a href="/JavaEE_Web_02_01code_war_exploded/img/女.jpg">展示圖片</a> 10 <a href="/JavaEE_Web_02_01code_war_exploded/DownloadServlet?filename=img/女.jpg ">下載圖片</a> 11 <a href="/JavaEE_Web_02_01code_war_exploded/img/女.png">展示圖片</a> 12 <a href="/JavaEE_Web_02_01code_war_exploded/DownloadServlet?filename=img/女.png">下載圖片</a> 13 </body> 14 </html>
2、后端代碼
1 package com.example.JavaEE_Web_02_01code.ServletContext; 2 3 import javax.servlet.ServletContext; 4 import javax.servlet.ServletException; 5 import javax.servlet.ServletOutputStream; 6 import javax.servlet.annotation.WebServlet; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 import java.io.File; 11 import java.io.FileInputStream; 12 import java.io.IOException; 13 import java.io.InputStream; 14 import java.util.ResourceBundle; 15 16 /** 17 * @Author: Promsing 18 * @Date: 2021/2/2 - 19:41 19 * @Description: 文件下載 20 * @version: 1.0 21 */ 22 23 @WebServlet("/DownloadServlet") 24 public class DownloadServlet extends HttpServlet { 25 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 26 //1.獲取請求參數,文件名稱 27 String filename = request.getParameter("filename"); 28 //2.使用字節輸入流加載文件到內存 29 ServletContext servletContext = this.getServletContext(); 30 String realPath = servletContext.getRealPath(filename); 31 FileInputStream fis=new FileInputStream(realPath); 32 //注意:設置response的響應頭 33 String mimeType = servletContext.getMimeType(filename); 34 response.setHeader("content-type",mimeType); 35 response.setHeader("content-disposition","attachment;filename"+filename); 36 //3.將輸入流的數據寫道輸出流中 37 ServletOutputStream sos = response.getOutputStream(); 38 byte[] bytes=new byte[1024*8]; 39 int len=0; 40 while ((len=fis.read(bytes))!=-1){ 41 sos.write(bytes,0,len); 42 } 43 //管理流 44 fis.close(); 45 }
46 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 47 this.doPost(request, response); 48 } 49 }
轉載至JavaWeb之Request與Response詳解:https://blog.csdn.net/promsing/article/details/113618924