者:滌生_Woo
一張圖帶你看完本篇文章
計算機網絡體系結構分層
利用 TCP/IP 協議族進行網絡通信時,會通過分層順序與對方進行通信。發送端從應用層往下走,接收端則從鏈路層往上走。如下:
TCP/IP 通信傳輸流
如下圖所示:
HTTP 請求
在網絡體系結構中,包含了眾多的網絡協議,這篇文章主要圍繞 HTTP 協議(HTTP/1.1版本)展開。
HTTP協議(HyperText Transfer Protocol,超文本傳輸協議)是用于從WWW服務器傳輸超文本到本地瀏覽器的傳輸協議。它可以使瀏覽器更加高效,使網絡傳輸減少。它不僅保證計算機正確快速地傳輸超文本文檔,還確定傳輸文檔中的哪一部分,以及哪部分內容首先顯示(如文本先于圖形)等。 HTTP是客戶端瀏覽器或其他程序與Web服務器之間的應用層通信協議。在Internet上的Web服務器上存放的都是超文本信息,客戶機需要通過HTTP協議傳輸所要訪問的超文本信息。HTTP包含命令和傳輸信息,不僅可用于Web訪問,也可以用于其他因特網/內聯網應用系統之間的通信,從而實現各類應用資源超媒體訪問的集成。 我們在瀏覽器的地址欄里輸入的網站地址叫做URL (Uniform Resource Locator,統一資源定位符)。就像每家每戶都有一個門牌地址一樣,每個網頁也都有一個Internet地址。當你在瀏覽器的地址框中輸入一個URL或是單擊一個超級鏈接時,URL就確定了要瀏覽的地址。瀏覽器通過超文本傳輸協議(HTTP),將Web服務器上站點的網頁代碼提取出來,并翻譯成漂亮的網頁。
HTTP請求響應模型
HTTP通信機制是在一次完整的 HTTP 通信過程中,客戶端與服務器之間將完成下列7個步驟:
應用 HTTP 協議時,必定是一端擔任客戶端角色,另一端擔任服務器端角色。僅從一條通信線路來說,服務器端和客服端的角色是確定的。HTTP 協議規定,請求從客戶端發出,最后服務器端響應該請求并返回。換句話說,肯定是先從客戶端開始建立通信的,服務器端在沒有接收到請求之前不會發送響應。
HTTP 是一種無狀態協議。協議自身不對請求和響應之間的通信狀態進行保存。也就是說在 HTTP 這個級別,協議對于發送過的請求或響應都不做持久化處理。這是為了更快地處理大量事務,確保協議的可伸縮性,而特意把 HTTP 協議設計成如此簡單的。 可是隨著 Web 的不斷發展,我們的很多業務都需要對通信狀態進行保存。于是我們引入了 Cookie 技術。有了 Cookie 再用 HTTP 協議通信,就可以管理狀態了。
Cookie 技術通過在請求和響應報文中寫入 Cookie 信息來控制客戶端的狀態。Cookie 會根據從服務器端發送的響應報文內的一個叫做 Set-Cookie 的首部字段信息,通知客戶端保存Cookie。當下次客戶端再往該服務器發送請求時,客戶端會自動在請求報文中加入 Cookie 值后發送出去。服務器端發現客戶端發送過來的 Cookie 后,會去檢查究竟是從哪一個客戶端發來的連接請求,然后對比服務器上的記錄,最后得到之前的狀態信息。
Cookie 的流程
HTTP 協議使用 URI 定位互聯網上的資源。正是因為 URI 的特定功能,在互聯網上任意位置的資源都能訪問到。
HTTP 方法
HTTP 協議的初始版本中,每進行一個 HTTP 通信都要斷開一次 TCP 連接。比如使用瀏覽器瀏覽一個包含多張圖片的 HTML 頁面時,在發送請求訪問 HTML 頁面資源的同時,也會請求該 HTML 頁面里包含的其他資源。因此,每次的請求都會造成無畏的 TCP 連接建立和斷開,增加通信量的開銷。 為了解決上述 TCP 連接的問題,HTTP/1.1 和部分 HTTP/1.0 想出了持久連接的方法。其特點是,只要任意一端沒有明確提出斷開連接,則保持 TCP 連接狀態。旨在建立一次 TCP 連接后進行多次請求和響應的交互。在 HTTP/1.1 中,所有的連接默認都是持久連接。
持久連接使得多數請求以管線化方式發送成為可能。以前發送請求后需等待并接收到響應,才能發送下一個請求。管線化技術出現后,不用等待亦可發送下一個請求。這樣就能做到同時并行發送多個請求,而不需要一個接一個地等待響應了。 比如,當請求一個包含多張圖片的 HTML 頁面時,與挨個連接相比,用持久連接可以讓請求更快結束。而管線化技術要比持久連接速度更快。請求數越多,時間差就越明顯。
用于 HTTP 協議交互的信息被稱為 HTTP 報文。請求端(客戶端)的 HTTP 報文叫做請求報文;響應端(服務器端)的叫做響應報文。HTTP 報文本身是由多行(用 CR+LF 作換行符)數據構成的字符串文本。
HTTP 報文大致可分為報文首部和報文主體兩部分。兩者由最初出現的空行(CR+LF)來劃分。通常,并不一定有報文主體。如下:
HTTP 報文結構
請求報文結構
請求報文的首部內容由以下數據組成:
請求報文的示例,如下:
請求報文示例
響應報文結構
響應報文的首部內容由以下數據組成:
響應報文的示例,如下:
響應報文示例
舉個栗子,下面是一個 HTTP 請求的報文:
GET /index.htm HTTP/1.1
Host: sample.com
其中,下面的這行就是請求行,
GET /index.htm HTTP/1.1
綜合來看,大意是請求訪問某臺 HTTP 服務器上的 /index.htm 頁面資源。
同樣舉個栗子,下面是一個 HTTP 響應的報文:
HTTP/1.1 200 OK
Date: Mon, 10 Jul 2017 15:50:06 GMT
Content-Length: 256
Content-Type: text/html
<html>
...
其中,下面的這行就是狀態行,
HTTP/1.1 200 OK
先來回顧一下首部字段在報文的位置,HTTP 報文包含報文首部和報文主體,報文首部包含請求行(或狀態行)和首部字段。 在報文眾多的字段當中,HTTP 首部字段包含的信息最為豐富。首部字段同時存在于請求和響應報文內,并涵蓋 HTTP 報文相關的內容信息。使用首部字段是為了給客服端和服務器端提供報文主體大小、所使用的語言、認證信息等內容。
首部字段名 冒號 字段值 Content-Type : text/html Keep-Alive : timeout=30, max=120
首部字段根據實際用途被分為以下4種類型:
類型 描述 通用首部字段 請求報文和響應報文兩方都會使用的首部 請求首部字段 從客戶端向服務器端發送請求報文時使用的首部。補充了請求的附加內容、客戶端信息、響應內容相關優先級等信息 響應首部字段 從服務器端向客戶端返回響應報文時使用的首部。補充了響應的附加內容,也會要求客戶端附加額外的內容信息。 實體首部字段 針對請求報文和響應報文的實體部分使用的首部。補充了資源內容更新時間等與實體有關的的信息。
首部字段名 說明 Cache-Control 控制緩存的行為 Connection 逐挑首部、連接的管理 Date 創建報文的日期時間 Pragma 報文指令 Trailer 報文末端的首部一覽 Transfer-Encoding 指定報文主體的傳輸編碼方式 Upgrade 升級為其他協議 Via 代理服務器的相關信息 Warning 錯誤通知
通過指定首部字段 Cache-Control 的指令,就能操作緩存的工作機制。
可用的指令按請求和響應分類如下: 緩存請求指令
指令 參數 說明 no-cache 無 強制向服務器再次驗證 no-store 無 不緩存請求或響應的任何內容 max-age=[秒] 必需 響應的最大Age值 max-stale(=[秒]) 可省略 接收已過期的響應 min-fresh=[秒] 必需 期望在指定時間內的響應仍有效 no-transform 無 代理不可更改媒體類型 only-if-cached 無 從緩存獲取資源 cache-extension - 新指令標記(token)
緩存響應指令
指令 參數 說明 public 無 可向任意方提供響應的緩存 private 可省略 僅向特定用戶返回響應 no-cache 可省略 緩存前必須先確認其有效性 no-store 無 不緩存請求或響應的任何內容 no-transform 無 代理不可更改媒體類型 must-revalidate 無 可緩存但必須再向源服務器進行確認 proxy-revalidate 無 要求中間緩存服務器對緩存的響應有效性再進行確認 max-age=[秒] 必需 響應的最大Age值 s-maxage=[秒] 必需 公共緩存服務器響應的最大Age值 cache-extension - 新指令標記(token)
public 指令 Cache-Control: public 當指定使用 public 指令時,則明確表明其他用戶也可利用緩存。
private 指令 Cache-Control: private 當指定 private 指令后,響應只以特定的用戶作為對象,這與 public 指令的行為相反。緩存服務器會對該特定用戶提供資源緩存的服務,對于其他用戶發送過來的請求,代理服務器則不會返回緩存。
no-cache 指令 Cache-Control: no-cache
Cache-Control: no-cache=Location 由服務器返回的響應中,若報文首部字段 Cache-Control 中對 no-cache 字段名具體指定參數值,那么客戶端在接收到這個被指定參數值的首部字段對應的響應報文后,就不能使用緩存。換言之,無參數值的首部字段可以使用緩存。只能在響應指令中指定該參數。
no-store 指令 Cache-Control: no-store 當使用 no-store 指令時,暗示請求(和對應的響應)或響應中包含機密信息。因此,該指令規定緩存不能在本地存儲請求或響應的任一部分。 注意:no-cache 指令代表不緩存過期的指令,緩存會向源服務器進行有效期確認后處理資源;no-store 指令才是真正的不進行緩存。
s-maxage 指令 Cache-Control: s-maxage=604800(單位:秒)
max-age 指令 Cache-Control: max-age=604800(單位:秒)
min-fresh 指令 Cache-Control: min-fresh=60(單位:秒) min-fresh 指令要求緩存服務器返回至少還未過指定時間的緩存資源。
max-stale 指令 Cache-Control: max-stale=3600(單位:秒)
only-if-cached 指令 Cache-Control: only-if-cached 表示客戶端僅在緩存服務器本地緩存目標資源的情況下才會要求其返回。換言之,該指令要求緩存服務器不重新加載響應,也不會再次確認資源的有效性。
must-revalidate 指令 Cache-Control: must-revalidate 使用 must-revalidate 指令,代理會向源服務器再次驗證即將返回的響應緩存目前是否仍有效。另外,使用 must-revalidate 指令會忽略請求的 max-stale 指令。
proxy-revalidate 指令 Cache-Control: proxy-revalidate proxy-revalidate 指令要求所有的緩存服務器在接收到客戶端帶有該指令的請求返回響應之前,必須再次驗證緩存的有效性。
no-transform 指令 Cache-Control: no-transform 使用 no-transform 指令規定無論是在請求還是響應中,緩存都不能改變實體主體的媒體類型。這樣做可防止緩存或代理壓縮圖片等類似操作。
Cache-Control: private, community="UCI" 通過 cache-extension 標記(token),可以擴展 Cache-Control 首部字段內的指令。上述 community 指令即擴展的指令,如果緩存服務器不能理解這個新指令,就會直接忽略掉。
Connection 首部字段具備以下兩個作用:
控制不再轉發的首部字段 Connection: Upgrade 在客戶端發送請求和服務器返回響應中,使用 Connection 首部字段,可控制不再轉發給代理的首部字段,即刪除后再轉發(即Hop-by-hop首部)。
管理持久連接 Connection: close HTTP/1.1 版本的默認連接都是持久連接。當服務器端想明確斷開連接時,則指定 Connection 首部字段的值為 close。 Connection: Keep-Alive HTTP/1.1 之前的 HTTP 版本的默認連接都是非持久連接。為此,如果想在舊版本的 HTTP 協議上維持持續連接,則需要指定 Connection 首部字段的值為 Keep-Alive。
表明創建 HTTP 報文的日期和時間。 Date: Mon, 10 Jul 2017 15:50:06 GMT HTTP/1.1 協議使用在 RFC1123 中規定的日期時間的格式。
Pragma 首部字段是 HTTP/1.1 版本之前的歷史遺留字段,僅作為與 HTTP/1.0 的向后兼容而定義。 Pragma: no-cache
Cache-Control: no-cache
Pragma: no-cache
Trailer: Expires 首部字段 Trailer 會事先說明在報文主體后記錄了哪些首部字段。可應用在 HTTP/1.1 版本分塊傳輸編碼時。
Transfer-Encoding: chunked
Upgrade: TSL/1.0 用于檢測 HTTP 協議及其他協議是否可使用更高的版本進行通信,其參數值可以用來指定一個完全不同的通信協議。
Via: 1.1 a1.sample.com(Squid/2.7)
該首部字段通常會告知用戶一些與緩存相關的問題的警告。 Warning 首部字段的格式如下: Warning:[警告碼][警告的主機:端口號] "[警告內容]"([日期時間]) 最后的日期時間可省略。 HTTP/1.1 中定義了7種警告,警告碼對應的警告內容僅推薦參考,另外,警告碼具備擴展性,今后有可能追加新的警告碼。
警告碼 警告內容 說明 110 Response is stale(響應已過期) 代理返回已過期的資源 111 Revalidation failed(再驗證失敗) 代理再驗證資源有效性時失敗(服務器無法到達等原因) 112 Disconnection operation(斷開連接操作) 代理與互聯網連接被故意切斷 113 Heuristic expiration(試探性過期) 響應的試用期超過24小時(有效緩存的設定時間大于24小時的情況下) 199 Miscellaneous warning(雜項警告) 任意的警告內容 214 Transformation applied(使用了轉換) 代理對內容編碼或媒體類型等執行了某些處理時 299 Miscellaneous persistent warning(持久雜項警告) 任意的警告內容
首部字段名 說明 Accept 用戶代理可處理的媒體類型 Accept-Charset 優先的字符集 Accept-Encoding 優先的內容編碼 Accept-Language 優先的語言(自然語言) Authorization Web認證信息 Expect 期待服務器的特定行為 From 用戶的電子郵箱地址 Host 請求資源所在服務器 If-Match 比較實體標記(ETag) If-Modified-Since 比較資源的更新時間 If-None-Match 比較實體標記(與 If-Macth 相反) If-Range 資源未更新時發送實體 Byte 的范圍請求 If-Unmodified-Since 比較資源的更新時間(與 If-Modified-Since 相反) Max-Forwards 最大傳輸逐跳數 Proxy-Authorization 代理服務器要求客戶端的認證信息 Range 實體的字節范圍請求 Referer 對請求中 URI 的原始獲取方 TE 傳輸編碼的優先級 User-Agent HTTP 客戶端程序的信息
Accept: text/html, application/xhtml+xml, application/xml; q=0.5
Accept-Charset: iso-8859-5, unicode-1-1; q=0.8 Accept-Charset 首部字段可用來通知服務器用戶代理支持的字符集及字符集的相對優先順序。另外,可一次性指定多種字符集。同樣使用 q=[數值] 來表示相對優先級。
Accept-Encoding: gzip, deflate Accept-Encoding 首部字段用來告知服務器用戶代理支持的內容編碼及內容編碼的優先順序,并可一次性指定多種內容編碼。同樣使用 q=[數值] 來表示相對優先級。也可使用星號(*)作為通配符,指定任意的編碼格式。
Accept-Lanuage: zh-cn,zh;q=0.7,en=us,en;q=0.3 告知服務器用戶代理能夠處理的自然語言集(指中文或英文等),以及自然語言集的相對優先級,可一次性指定多種自然語言集。同樣使用 q=[數值] 來表示相對優先級。
Authorization: Basic ldfKDHKfkDdasSAEdasd==告知服務器用戶代理的認證信息(證書值)。通常,想要通過服務器認證的用戶代理會在接收到返回的 401 狀態碼響應后,把首部字段 Authorization 加入請求中。共用緩存在接收到含有 Authorization 首部字段的請求時的操作處理會略有差異。
Expect: 100-continue 告知服務器客戶端期望出現的某種特定行為。
From: Deeson_Woo@163.com 告知服務器使用用戶代理的電子郵件地址。
Host: www.jianshu.com
形如 If-xxx 這種樣式的請求首部字段,都可稱為條件請求。服務器接收到附帶條件的請求后,只有判斷指定條件為真時,才會執行請求。
If-Match: "123456"
If-Modified-Since: Mon, 10 Jul 2017 15:50:06 GMT
If-None-Match: "123456" 首部字段 If-None-Match 屬于附帶條件之一。它和首部字段 If-Match 作用相反。用于指定 If-None-Match 字段值的實體標記(ETag)值與請求資源的 ETag 不一致時,它就告知服務器處理該請求。
If-Range: "123456"
If-Unmodified-Since: Mon, 10 Jul 2017 15:50:06 GMT 首部字段 If-Unmodified-Since 和首部字段 If-Modified-Since 的作用相反。它的作用的是告知服務器,指定的請求資源只有在字段值內指定的日期時間之后,未發生更新的情況下,才能處理請求。如果在指定日期時間后發生了更新,則以狀態碼 412 Precondition Failed 作為響應返回。
Max-Forwards: 10 通過 TRACE 方法或 OPTIONS 方法,發送包含首部字段 Max-Forwards 的請求時,該字段以十進制整數形式指定可經過的服務器最大數目。服務器在往下一個服務器轉發請求之前,Max-Forwards 的值減 1 后重新賦值。當服務器接收到 Max-Forwards 值為 0 的請求時,則不再進行轉發,而是直接返回響應。
Proxy-Authorization: Basic dGlwOjkpNLAGfFY5
Range: bytes=5001-10000
Referer: http://www.sample.com/index.html 首部字段 Referer 會告知服務器請求的原始資源的 URI。
TE: gzip, deflate; q=0.5
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101
首部字段名 說明 Accept-Ranges 是否接受字節范圍請求 Age 推算資源創建經過時間 ETag 資源的匹配信息 Location 令客戶端重定向至指定 URI Proxy-Authenticate 代理服務器對客戶端的認證信息 Retry-After 對再次發起請求的時機要求 Server HTTP 服務器的安裝信息 Vary 代理服務器緩存的管理信息 WWW-Authenticate 服務器對客戶端的認證信息
Accept-Ranges: bytes
Age: 1200
ETag: "usagi-1234"
Location: http://www.sample.com/sample.html
Proxy-Authenticate: Basic realm="Usagidesign Auth"
Retry-After: 180
Server: Apache/2.2.6 (Unix) PHP/5.2.5 首部字段 Server 告知客戶端當前服務器上安裝的 HTTP 服務器應用程序的信息。不單單會標出服務器上的軟件應用名稱,還有可能包括版本號和安裝時啟用的可選項。
Vary: Accept-Language
WWW-Authenticate: Basic realm="Usagidesign Auth" 首部字段 WWW-Authenticate 用于 HTTP 訪問認證。它會告知客戶端適用于訪問請求 URI 所指定資源的認證方案(Basic 或是 Digest)和帶參數提示的質詢(challenge)。
首部字段名 說明 Allow 資源可支持的 HTTP 方法 Content-Encoding 實體主體適用的編碼方式 Content-Language 實體主體的自然語言 Content-Length 實體主體的大小(單位:字節) Content-Location 替代對應資源的 URI Content-MD5 實體主體的報文摘要 Content-Range 實體主體的位置范圍 Content-Type 實體主體的媒體類型 Expires 實體主體過期的日期時間 Last-Modified 資源的最后修改日期時間
Allow: GET, HEAD
Content-Encoding: gzip
Content-Language: zh-CN 首部字段 Content-Language 會告知客戶端,實體主體使用的自然語言(指中文或英文等語言)。
Content-Length: 15000 首部字段 Content-Length 表明了實體主體部分的大小(單位是字節)。對實體主體進行內容編碼傳輸時,不能再使用 Content-Length首部字段。
Content-Location: http://www.sample.com/index.html 首部字段 Content-Location 給出與報文主體部分相對應的 URI。和首部字段 Location 不同,Content-Location 表示的是報文主體返回資源對應的 URI。
Content-MD5: OGFkZDUwNGVhNGY3N2MxMDIwZmQ4NTBmY2IyTY==首部字段 Content-MD5 是一串由 MD5 算法生成的值,其目的在于檢查報文主體在傳輸過程中是否保持完整,以及確認傳輸到達。
Content-Range: bytes 5001-10000/10000 針對范圍請求,返回響應時使用的首部字段 Content-Range,能告知客戶端作為響應返回的實體的哪個部分符合范圍請求。字段值以字節為單位,表示當前發送部分及整個實體大小。
Content-Type: text/html; charset=UTF-8 首部字段 Content-Type 說明了實體主體內對象的媒體類型。和首部字段 Accept 一樣,字段值用 type/subtype 形式賦值。參數 charset 使用 iso-8859-1 或 euc-jp 等字符集進行賦值。
Expires: Mon, 10 Jul 2017 15:50:06 GMT
Last-Modified: Mon, 10 Jul 2017 15:50:06 GMT 首部字段 Last-Modified 指明資源最終修改的時間。一般來說,這個值就是 Request-URI 指定資源被修改的時間。但類似使用 CGI 腳本進行動態數據處理時,該值有可能會變成數據最終修改時的時間。
首部字段名 說明 首部類型 Set-Cookie 開始狀態管理所使用的 Cookie 信息 響應首部字段 Cookie 服務器接收到的 Cookie 信息 請求首部字段
Set-Cookie: status=enable; expires=Mon, 10 Jul 2017 15:50:06 GMT; path=/;
下面的表格列舉了 Set-Cookie 的字段值。
屬性 說明 NAME=VALUE 賦予 Cookie 的名稱和其值(必需項) expires=DATE Cookie 的有效期(若不明確指定則默認為瀏覽器關閉前為止) path=PATH 將服務器上的文件目錄作為Cookie的適用對象(若不指定則默認為文檔所在的文件目錄) domain=域名 作為 Cookie 適用對象的域名 (若不指定則默認為創建 Cookie的服務器的域名) Secure 僅在 HTTPS 安全通信時才會發送 Cookie HttpOnly 加以限制,使 Cookie 不能被 JavaScript 腳本訪問
Cookie 的 path 屬性可用于限制指定 Cookie 的發送范圍的文件目錄。
Cookie 的 secure 屬性用于限制 Web 頁面僅在 HTTPS 安全連接時,才可以發送 Cookie。
Cookie: status=enable 首部字段 Cookie 會告知服務器,當客戶端想獲得 HTTP 狀態管理支持時,就會在請求中包含從服務器接收到的 Cookie。接收到多個 Cookie 時,同樣可以以多個 Cookie 形式發送。
HTTP 首部字段是可以自行擴展的。所以在 Web 服務器和瀏覽器的應用上,會出現各種非標準的首部字段。 以下是最為常用的首部字段。
X-Frame-Options: DENY 首部字段 X-Frame-Options 屬于 HTTP 響應首部,用于控制網站內容在其他 Web 網站的 Frame 標簽內的顯示問題。其主要目的是為了防止點擊劫持(clickjacking)攻擊。首部字段 X-Frame-Options 有以下兩個可指定的字段值:
X-XSS-Protection: 1 首部字段 X-XSS-Protection 屬于 HTTP 響應首部,它是針對跨站腳本攻擊(XSS)的一種對策,用于控制瀏覽器 XSS 防護機制的開關。首部字段 X-XSS-Protection 可指定的字段值如下:
DNT: 1 首部字段 DNT 屬于 HTTP 請求首部,其中 DNT 是 Do Not Track 的簡稱,意為拒絕個人信息被收集,是表示拒絕被精準廣告追蹤的一種方法。首部字段 DNT 可指定的字段值如下:
由于首部字段 DNT 的功能具備有效性,所以 Web 服務器需要對 DNT做對應的支持。
P3P: CP="CAO DSP LAW CURa ADMa DEVa TAIa PSAa PSDa IVAa IVDa OUR BUS IND 首部字段 P3P 屬于 HTTP 響應首部,通過利用 P3P(The Platform for Privacy Preferences,在線隱私偏好平臺)技術,可以讓 Web 網站上的個人隱私變成一種僅供程序可理解的形式,以達到保護用戶隱私的目的。 要進行 P3P 的設定,需按以下操作步驟進行:
類別 原因短語 1xx Informational(信息性狀態碼) 接收的請求正在處理 2xx Success(成功狀態碼) 請求正常處理完畢 3xx Redirection(重定向狀態碼) 需要進行附加操作以完成請求 4xx Client Error(客戶端錯誤狀態碼) 服務器無法處理請求 5xx Server Error(服務器錯誤狀態碼) 服務器處理請求出錯
我們可以自行改變 RFC2616 中定義的狀態碼或者服務器端自行創建狀態碼,只要遵守狀態碼的類別定義就可以了。
HTTP 狀態碼種類繁多,數量達幾十種。其中最常用的有以下 14 種,一起來看看。
表示從客戶端發來的請求在服務器端被正常處理了。
表示客戶端進行了范圍請求,而服務器成功執行了這部分的 GET 請求。響應報文中包含由 Content-Range 首部字段指定范圍的實體內容。
永久性重定向。表示請求的資源已被分配了新的 URI。以后應使用資源現在所指的 URI。也就是說,如果已經把資源對應的 URI 保存為書簽了,這時應該按 Location 首部字段提示的 URI 重新保存。
臨時重定向。該狀態碼與 302 Found 有著相同的含義。
表明對請求資源的訪問被服務器拒絕了。服務器端沒有必要給出詳細的拒絕理由,當然也可以在響應報文的實體主體部分對原因進行描述。
表明服務器上無法找到請求的資源。除此之外,也可以在服務器端拒絕請求且不想說明理由的時候使用。
表明服務器端在執行請求時發生了錯誤。也可能是 Web 應用存在的 bug 或某些臨時的故障。
表明服務器暫時處于超負載或正在進行停機維護,現在無法處理請求。如果事先得知解除以上狀況需要的時間,最好寫入 Retry-After 首部字段再返回給客戶端。
HTTP 報文結構
大家請仔細看看上面示例中,各個組成部分對應的內容。 接著,我們來看看報文和實體的概念。如果把 HTTP 報文想象成因特網貨運系統中的箱子,那么 HTTP 實體就是報文中實際的貨物。
我們可以看到,上面示例右圖中深紅色框的內容就是報文的實體部分,而藍色框的兩部分內容分別就是實體首部和實體主體。而左圖中粉紅框內容就是報文主體。 通常,報文主體等于實體主體。只有當傳輸中進行編碼操作時,實體主體的內容發生變化,才導致它和報文主體產生差異。
內容編碼類型:
編碼方式 描述 gzip 表明實體采用 GNU zip 編碼 compress 表明實體采用 Unix 的文件壓縮程序 deflate 表明實體采用 zlib 的格式壓縮的 identity 表明沒有對實體進行編碼,當沒有 Content-Encoding 首部字段時,默認采用此編碼方式
內容編碼是對報文的主體進行的可逆變換,是和內容的具體格式細節緊密相關的。 傳輸編碼也是作用在實體主體上的可逆變換,但使用它們是由于架構方面的原因,同內容的格式無關。使用傳輸編碼是為了改變報文中的數據在網絡上傳輸的方式。
內容編碼和傳輸編碼的對比
分塊編碼把報文分割成若干已知大小的塊。塊之間是緊挨著發送的,這樣就不需要在發送之前知道整個報文的大小了。分塊編碼是一種傳輸編碼,是報文的屬性。
分塊編碼與持久連接 若客戶端與服務器端之間不是持久連接,客戶端就不需要知道它在讀取的主體的長度,而只需要讀取到服務器關閉主體連接為止。 當使用持久連接時,在服務器寫主體之前,必須知道它的大小并在 Content-Length 首部中發送。如果服務器動態創建內容,就可能在發送之前無法知道主體的長度。 分塊編碼為這種困難提供了解決方案,只要允許服務器把主體分塊發送,說明每塊的大小就可以了。因為主體是動態創建的,服務器可以緩沖它的一部分,發送其大小和相應的塊,然后在主體發送完之前重復這個過程。服務器可以用大小為 0 的塊作為主體結束的信號,這樣就可以繼續保持連接,為下一個響應做準備。 來看看一個分塊編碼的報文示例:
分塊編碼的報文
MIME 中的 multipart(多部分)電子郵件報文中包含多個報文,它們合在一起作為單一的復雜報文發送。每一部分都是獨立的,有各自的描述其內容的集,不同部分之間用分界字符串連接在一起。 相應得,HTTP 協議中也采納了多部分對象集合,發送的一份報文主體內可包含多種類型實體。 多部分對象集合包含的對象如下:
假設你正在下載一個很大的文件,已經下了四分之三,忽然網絡中斷了,那下載就必須重頭再來一遍。為了解決這個問題,需要一種可恢復的機制,即能從之前下載中斷處恢復下載。要實現該功能,這就要用到范圍請求。 有了范圍請求, HTTP 客戶端可以通過請求曾獲取失敗的實體的一個范圍(或者說一部分),來恢復下載該實體。當然這有一個前提,那就是從客戶端上一次請求該實體到這一次發出范圍請求的時間段內,該對象沒有改變過。例如:
GET /bigfile.html HTTP/1.1
Host: www.sample.com
Range: bytes=20224-
···
實體范圍請求示例
上面示例中,客戶端請求的是文檔開頭20224字節之后的部分。
HTTP 通信時,除客戶端和服務器外,還有一些用于協助通信的應用程序。如下列出比較重要的幾個:代理、緩存、網關、隧道、Agent 代理。
代理
HTTP 代理服務器是 Web 安全、應用集成以及性能優化的重要組成模塊。代理位于客戶端和服務器端之間,接收客戶端所有的 HTTP 請求,并將這些請求轉發給服務器(可能會對請求進行修改之后再進行轉發)。對用戶來說,這些應用程序就是一個代理,代表用戶訪問服務器。 出于安全考慮,通常會將代理作為轉發所有 Web 流量的可信任中間節點使用。代理還可以對請求和響應進行過濾,安全上網或綠色上網。
瀏覽器第一次請求:
瀏覽器第一次請求
瀏覽器再次請求:
瀏覽器再次請求
Web 緩存或代理緩存是一種特殊的 HTTP 代理服務器,可以將經過代理傳輸的常用文檔復制保存起來。下一個請求同一文檔的客戶端就可以享受緩存的私有副本所提供的服務了。客戶端從附近的緩存下載文檔會比從遠程 Web 服務器下載快得多。
HTTP / FTP 網關
網關是一種特殊的服務器,作為其他服務器的中間實體使用。通常用于將 HTTP 流量轉換成其他的協議。網關接收請求時就好像自己是資源的源服務器一樣。客戶端可能并不知道自己正在跟一個網關進行通信。
HTTP/SSL 隧道
隧道是會在建立起來之后,就會在兩條連接之間對原始數據進行盲轉發的 HTTP 應用程序。HTTP 隧道通常用來在一條或多條 HTTP 連接上轉發非 HTTP 數據,轉發時不會窺探數據。 HTTP 隧道的一種常見用途就是通過 HTTP 連接承載加密的安全套接字層(SSL)流量,這樣 SSL 流量就可以穿過只允許 Web 流量通過的防火墻了。
自動搜索引擎“網絡蜘蛛”
Agent 代理是代表用戶發起 HTTP 請求的客戶端應用程序。所有發布 Web 請求的應用程序都是 HTTP Agent 代理。
原文鏈接:https://www.jianshu.com/p/6e9e4156ece3
TTP(Hypertext Transfer Protocol,超文本傳輸協議)是互聯網中使用最廣泛的通信協議之一,它定義了客戶端與服務器之間的通信規則。無論是瀏覽網頁、調用 API、下載文件,還是進行各種在線交互,HTTP 都是不可或缺的基礎協議。HTTP 協議基于請求-響應模型工作,其中客戶端發出請求,服務器返回響應。HTTP 請求方法定義了客戶端希望執行的操作類型,每種請求方法都有特定的用途和行為。
在 HTTP/1.1 中,標準定義了多種請求方法,每種方法適用于不同的場景。本文將詳細介紹九種 HTTP 請求方法:GET、POST、PUT、DELETE、PATCH、HEAD、CONNECT、OPTIONS 和 TRACE。這些方法在 Web 開發和 API 設計中扮演著重要角色。通過理解這些請求方法的功能和使用場景,開發者可以更好地設計和優化網絡應用程序。
GET 方法是 HTTP 中最常用的請求方法之一,幾乎在所有的 Web 應用中都能看到它的身影。GET 請求的主要作用是從服務器獲取資源,例如網頁、圖片、視頻等。當用戶在瀏覽器中輸入一個 URL 并按下回車鍵時,瀏覽器便會向服務器發送一個 GET 請求,要求獲取該 URL 對應的資源。服務器處理請求后,會將資源發送回客戶端,通常是 HTML、CSS、JavaScript 文件或其他媒體內容。
GET 方法的主要作用是從服務器請求數據,而不會對服務器上的資源進行任何修改。換句話說,GET 請求是"無副作用"的,不會改變服務器的狀態。GET 請求通常用于以下場景:
示例:
GET /index.html HTTP/1.1
Host: www.example.com
在上述示例中,客戶端通過 GET 請求從服務器獲取 index.html 文件。服務器在處理該請求后,會返回相應的 HTML 文件給客戶端。
GET 請求廣泛應用于 Web 開發中,尤其是在需要從服務器獲取數據的場景中。例如:
示例:
GET /search?q=http GET method HTTP/1.1
Host: www.searchengine.com
示例:
GET /product/12345 HTTP/1.1
Host: www.onlinestore.com
GET 請求的一個重要特性是可以被緩存。瀏覽器或中間代理服務器可以緩存 GET 請求的響應,以減少重復請求服務器的次數,從而提高性能并降低帶寬消耗。HTTP 協議中定義了多種緩存機制,例如 ETag、Last-Modified 等,它們用于標識資源的狀態,判斷資源是否已改變。
緩存示例:
GET /logo.png HTTP/1.1
Host: www.example.com
If-None-Match: "abc123"
如果服務器返回的 ETag 與緩存中的 ETag 匹配,瀏覽器將直接使用緩存中的資源,而不重新下載文件。這不僅節省了帶寬,還加快了頁面加載速度。
GET 請求中常見的一種形式是通過 URL 參數或查詢字符串傳遞數據。查詢字符串通常附加在 URL 的末尾,以 ? 開頭,參數與值之間用 = 連接,多個參數之間用 & 分隔。
示例:
GET /search?q=HTTP+GET+method&sort=latest HTTP/1.1
Host: www.example.com
在上述請求中,查詢字符串 q=HTTP+GET+method&sort=latest 包含了兩個參數:q 和 sort,分別表示搜索關鍵詞和排序方式。這種方式適合傳遞簡單的鍵值對數據,但由于查詢字符串會暴露在 URL 中,因此不適合傳輸敏感信息。
盡管 GET 請求廣泛使用,但在安全性方面需要注意以下幾點:
為了增強安全性,建議在傳輸敏感數據時使用 POST 方法,并通過 HTTPS 加密通信。
POST 方法用于向服務器發送數據,通常是為了提交表單、上傳文件、或調用 API 接口以進行數據處理。與 GET 方法不同,POST 請求的數據不會附加在 URL 中,而是包含在請求體中。因此,POST 方法適合傳輸較大或敏感的數據。
POST 方法的典型使用場景包括:
示例:
POST /submit-form HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
username=johndoe&password=secret123
示例:
POST /upload HTTP/1.1
Host: www.example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="example.jpg"
Content-Type: image/jpeg
(binary file data)
------WebKitFormBoundary--
示例:
POST /api/users HTTP/1.1
Host: www.example.com
Content-Type: application/json
{
"username": "johndoe",
"email": "johndoe@example.com",
"password": "secret123"
}
POST 請求是非冪等的,這意味著重復發送相同的 POST 請求可能會產生不同的結果。例如,重復提交訂單或評論可能會導致服務器生成多個相同的記錄。由于這一特性,開發者在設計 API 時通常需要考慮如何防止重復提交的問題,例如使用唯一性約束、token 驗證等手段。
與 GET 請求相比,POST 請求在安全性方面有一些顯著的優勢:
盡管如此,POST 請求仍然需要配合 HTTPS 協議使用,以確保數據在傳輸過程中的安全性。使用 HTTPS 可以加密數據,防止在傳輸過程中被竊取或篡改。
PUT 方法通常用于更新服務器上的資源。與 POST 方法不同,PUT 請求是冪等的,意味著多次發送相同的 PUT 請求,服務器的資源狀態不會變化。PUT 方法可以用于創建或更新資源,通常用于更新現有資源的數據。
PUT 方法的典型使用場景包括:
示例:
PUT /api/users/123 HTTP/1.1
Host: www.example.com
Content-Type: application/json
{
"username": "johndoe",
"email": "newemail@example.com"
}
示例:
PUT /documents/456 HTTP/1.1
Host: www.example.com
Content-Type: text/plain
Updated document content...
PUT 方法是冪等的,這意味著相同的 PUT 請求無論執行多少次,服務器上的資源狀態應保持一致。例如,用戶修改個人資料后,如果重復發送相同的 PUT 請求,服務器上該用戶的資料應保持不變,而不會生成多個相同的記錄。
PUT 請求通常用于更新現有資源,因此在安全性方面需要特別注意以下幾點:
DELETE 方法用于刪除服務器上的指定資源。在 RESTful API 設計中,DELETE 方法通常用于移除指定的資源對象或數據。例如,刪除一篇文章、一條評論、或一個用戶賬戶等。DELETE 方法的冪等性特性決定了無論同一個 DELETE 請求被執行多少次,服務器上的資源狀態應保持一致,即資源被刪除后,再次刪除操作不會產生任何新的效果。
DELETE 方法的典型使用場景包括:
DELETE 方法是冪等的,這意味著相同的 DELETE 請求無論執行多少次,服務器上的資源狀態應保持一致。例如,發送 DELETE 請求刪除一篇文章,如果文章已經被刪除,再次發送相同的 DELETE 請求不會導致新的變化,服務器應返回一個指示資源已不存在的響應。
DELETE 請求涉及到資源的刪除操作,因此需要特別注意以下幾個方面的安全性問題:
PATCH 方法用于對服務器上的資源進行部分更新。與 PUT 方法不同,PATCH 請求不需要包含完整的資源數據,而只需要傳輸需要更新的部分字段。因此,PATCH 方法非常適合用于需要頻繁更新部分數據的場景。
PATCH 方法的典型使用場景包括:
示例:
PATCH /api/users/123 HTTP/1.1
Host: www.example.com
Content-Type: application/json
{
"email": "newemail@example.com"
}
示例:
PATCH /documents/456 HTTP/1.1
Host: www.example.com
Content-Type: application/json
{
"title": "Updated Document Title"
}
PATCH 方法通常被認為是非冪等的,這意味著相同的 PATCH 請求被執行多次可能會產生不同的結果。例如,如果一個 PATCH 請求是對字符串數據進行追加操作,那么重復執行相同的請求將會導致字符串的內容被多次追加,產生不同的結果。
然而,也有特定情況下的 PATCH 請求是冪等的,例如只是對某個字段的值進行覆蓋更新。在這種情況下,PATCH 請求的冪等性與 PUT 方法類似。
PATCH 請求主要用于部分更新,因此在安全性方面需注意以下幾點:
HEAD 方法與 GET 方法非常相似,但它只請求資源的首部信息,而不包含資源的具體內容。HEAD 請求的響應中只有狀態行和頭部字段,不返回消息體。HEAD 方法通常用于在不下載資源的情況下獲取資源的元數據,如檢查資源是否存在、獲取資源的大小或類型等。
HEAD 方法的典型使用場景包括:
示例:
HEAD /files/sample.pdf HTTP/1.1
Host: www.example.com
示例:
HEAD /api/documents/456 HTTP/1.1
Host: www.example.com
HEAD 方法的一個顯著特點是它不會返回消息體,因此在獲取資源元數據時,HEAD 請求比 GET 請求更加高效。此外,由于 HEAD 請求不會返回資源內容,它通常被用作緩存控制的手段。例如,通過 HEAD 請求檢查資源的 Last-Modified 或 ETag 頭部字段,客戶端可以決定是否需要重新下載資源。
CONNECT 方法用于建立一個到服務器的隧道連接,通常用于 HTTP 與 HTTPS 的代理請求。CONNECT 請求會將客戶端的連接轉換為一個雙向通信的通道,允許客戶端與目標服務器之間傳遞任意數據而不受代理服務器的影響。最常見的應用場景是通過 HTTP 代理訪問 HTTPS 站點。
CONNECT 方法的典型使用場景包括:
示例:
CONNECT www.example.com:443 HTTP/1.1
Host: www.example.com
當代理服務器收到這個請求后,會建立一個與目標服務器的 TCP 連接,并將后續的所有數據直接傳遞給目標服務器。這種方式允許客戶端與目標服務器之間的通信保持安全性和私密性,因為代理服務器只負責傳遞數據,而不進行解析或修改。
由于 CONNECT 方法用于創建一個隧道連接,它能夠有效地維護客戶端與服務器之間的通信隱私。然而,CONNECT 方法也可能被濫用。例如,惡意用戶可以利用 CONNECT 方法繞過防火墻或其他網絡安全措施,進行未經授權的訪問。因此,許多代理服務器在使用 CONNECT 方法時會對目標端口或目標域名進行限制,防止濫用。
OPTIONS 方法用于查詢服務器支持的請求方法或特定資源所支持的功能。它通常用于檢查服務器的能力,確定哪些請求方法可以被安全地執行在指定資源上。OPTIONS 請求的響應通常包括 Allow 頭部字段,列出服務器支持的請求方法。
OPTIONS 方法的典型使用場景包括:
示例:
OPTIONS /api/users HTTP/1.1
Host: api.example.com
響應示例:
HTTP/1.1 204 No Content
Allow: GET, POST, PUT, DELETE
示例:
OPTIONS /documents/456 HTTP/1.1
Host: www.example.com
響應示例:
HTTP/1.1 200 OK
Allow: GET, POST, DELETE, OPTIONS
OPTIONS 方法廣泛用于 CORS 機制中,以確保跨域請求的安全性和合規性。通過預檢請求,服務器可以控制哪些外部來源和請求方法可以訪問其資源,從而避免跨站請求偽造(CSRF)攻擊。
此外,OPTIONS 方法也可以用于測試和診斷服務器的配置,幫助開發者或管理員了解服務器的請求處理能力。
TRACE 方法用于在服務器上發起一個回環測試,即服務器將收到的請求原樣返回給客戶端。TRACE 方法的主要用途是診斷或調試,幫助客戶端檢查請求在傳輸過程中是否被修改或損壞。
TRACE 請求的典型使用場景包括:
示例:
TRACE /api/resource HTTP/1.1
Host: www.example.com
響應示例:
HTTP/1.1 200 OK
Content-Type: message/http
TRACE /api/resource HTTP/1.1
Host: www.example.com
User-Agent: MyBrowser/1.0
由于 TRACE 方法會將請求的所有信息,包括可能包含的敏感數據,如 Cookies 或 Authorization 頭部,返回給客戶端,這可能導致信息泄露。攻擊者可以利用 TRACE 方法實施跨站點跟蹤攻擊(Cross-Site Tracing,XST),獲取用戶的敏感信息。因此,許多現代的 Web 服務器默認禁用 TRACE 方法以防止潛在的安全風險。
CORS ( Cross Origin Resource Sharing,跨域資源共享)機制允許Web應用服務器進行跨域訪問控制,從而使跨域數據傳輸得以安全進行。瀏覽器支持在API容器中(如XMLHttpRequest或Fetch )使用CORS,以降低跨域HTTP請求所帶來的風險。
本節將介紹如何在Spring Boot應用中,實現跨域訪問資源。
當一個資源從與該資源本身所在的服務器不同的域或端口請求一一個資源時, 資源會發起- - 個跨域HTTP請求。
比如,站點ht://example-a.com 的某HTML頁面通過<img>的src請求htp://example-b.com/image.jpg。網絡上的許多頁面都會加載來自不同域的CSS樣式表、圖像和腳本等資源。
W3C制定了CORS的相關規范,見hts://ww.w3.org/TR/cors/。出于安全考慮,瀏覽器會限制從腳本內發起的跨域HTTP請求。例如,XMLHttpRequest 和Fetch遵循同源策略。因此,使用XMLHtpRequest或Fetch的Web應用程序只能將HTTP請求發送到其自己的域。為了改進Web應用程序,開發人員要求瀏覽器廠商允許跨域請求。
識別是否具有跨域行為,是由同源政策決定的。同源政策由Netscape 公司引入瀏覽器。目前,所有瀏覽器都實行這個政策。所謂“同源”, 指的是“三個相同”。
協議相同。
●域名相同。
● 端口相同。
舉例來說,htp://example.com/page.html 這個網址,協議是htp://, 域名是www.example.com,端口是80 (默認端口可以省略)。它的同源情況如下。
http://example. com/other.html:同源。
● ht://www.example.com/other.html: 不同源,域名不同。
● htp://v2.example.com/other.html: 不同源,域名不同。
● htp://example.com:81/other.html: 不同源,端口不同。
在微服務的架構里面,由于每個服務都在其自身的源中運行,因此,很容易就會遇到來自多個來源的客戶端Web應用程序來訪問服務的問題(即跨域訪問)。例如,- -個瀏覽器客戶端從“客戶”
微服務器訪問“客戶”,并從“訂單”微服務器訪問訂單歷史記錄,這種做法在微服務領域非常普遍。
Spring MVC支持CORS的開箱即用的功能。主要有兩種實現跨域訪問的方式。
1.方法級別的跨域訪問
Spring Boot提供了一種簡單的聲明式方法來實現跨域請求。以下示例顯示如何使用@CrossOr-igin注解,來啟用允許跨域訪問某些接口。
import org. springf ramework. web. bind. annotation. CrossOrigin;
@CrossOrigin(origins="*", maxAge=3600) // 允許所有域名訪問
@Controller
public class FileController {
//..
}
其中,origins="**意味著允許所有域名訪問(當然,你也可以限定某個域名來訪問)。maxAge=3600是指有效期為3600秒。
2.全局跨域訪問
可以通過使用自定義的addCorsMappings(CorsRegistry)方法注冊WebMvcConfigurer bean來定義全局CORS配置。用法如下。
@Configuration
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer () {
@Override
public void addCorsMappings (CorsRegistry registry){
registry. addMapping ("/api/**");
};
}}
消息通信是企業信息集成中非常重要的一種方式。
消息的通信一般是由消息隊列系統( MessageQueuing System, MQ )或面向消息中間件( Message Oriented Middleware, MOM )來提供高效可靠的消息傳遞機制進行平臺無關的數據交流,并可基于數據通信進行分布式系統的集成。通過提供消息傳遞和消息排隊模型,可在分布環境下擴展進程間的通信,并支持多種通信協議、語言、應用程序、硬件和軟件平臺。
通過使用MQ或MOM,通信雙方的程序(稱其為消息客戶程序)可以在不同的時間運行,程序不在網絡.上直接通話,而是間接地將消息放入MQ或MOM服務器的消息隊列中。因為程序間沒有直接的聯系,所以它們不必同時運行:消息放入適當的隊列時,目標程序不需要正在運行;即使目標程序在運行,也不意味著要立即處理該消息。
消息客戶程序之間通過將消息放入消息隊列或從消息隊列中取出消息來進行通信。客戶程序不直接與其他程序通信,避免了網絡通信的復雜性。消息隊列和網絡通信的維護工作由MQ或MOM完成。
常見的MQ或MOM產品有Java Message Service、 Apache ActiveMQ、Apache RocketMQ、RabbitMQ、Apache Kafka等。
對于Spring應用而言,Spring Boot針對Java Message Service、RabbitMQ、 Apache Kafka等提供了開箱即用的支持。
Java Message Service ( JMS ) API是- -個 Java面向消息中間件的API,用于兩個或多個客戶端之間發送消息。
JMS的目標包括:
●包含實現復雜企業應用所需要的功能特性;
●定義了企業消息概念和功能的一組通用集合;
●最小化企業消息產品的概念,以降低學習成本。
最大化消息應用的可移植性。
JMS支持企業消息產品提供以下兩種主要的消息風格。
●點對點 (Point-to-Point, PTP )消息風格:允許一個客戶端通過-一個叫“隊列( queue)”的中間抽象發送一個消息給另- 一個客戶端。發送消息的客戶端將-一個消息發送 到指定的隊列中,接收消息的客戶端從這個隊列中抽取消息。
●發布訂閱( Publish/Subscribe, Pub/Sub )消息風格:允許-一個客戶端通過-一個叫“主題( topic )”的中間抽象發送一個消息給多個客 戶端。發送消息的客戶端將一個消 息發布到指定的主題中,然后這個消息將被投遞到所有訂閱了這個主題的客戶端。
在Spring Boot應用中使用JMS,通常需要以下幾個步驟。
1.使用JNDI ConnectionFactory
在應用程序中,Spring Boot將嘗試使用JNDI找到JMS ConnectionFactory。 默認情況下,將檢查位置java:/JmsXA和java:/XAConnectionFactory。如果需要指定其他位置,可以使用spring.jms.jndi-name屬性。
spring.jms.jndi-name=java:/MyConnectionFactory
2.發送消息
Spring的JmsTemplate是自動配置的,可以將其直接自動裝配到自己的bean中。
import org. springf ramework. beans. factory . annotation. Autowired;
import org. spr ingframework. jms . core . JmsTemplate;
import org. spr ingframework. stereotype . Component;
@Component
public class MyBean
private final JmsTemplate jmsTemplate;
@Autowi red
public MyBean (JmsTemplate jmsTemplate) {
this. jmsTemplate=jmsTemplate;
3.接收消息
在JMS架構中,可以使用@JmsListener來注解任何bean,以創建偵聽器端點。如果沒有定義JmsListenerContainerFactory,則會自動配置默認值。如果定義了DestinationResolver 或Message-Converter bean,則它們將自動關聯到默認工廠。
默認工廠是事務性的。如果在JtaTransactionManager 存在的基礎架構中運行,則默認情況下將
與偵聽器容器相關聯。如果沒有,sessionTransacted 標志將被啟用。在后一種情況下, 可以通過在
偵聽器方法(或其代理)上添加@Transactional來將本地數據存儲事務關聯到傳入消息的處理。這
將確保在本地事務完成后確認傳入的消息。這還包括發送在同-一個JMS會話上執行的響應消息。
以下案例在someQueue目標上創建一個 偵聽器端點。
@Component
public class MyBean {
@JmsListener (destination="someQueue")
public void processMessage (String content) {
}
}
RabbitMQ是更高級別的消息中間件,實現了Advanced Message Queuing Protocol( AMQP )協議。
Spring AMQP項目將核心Spring 概念應用于基于AMQP的消息傳遞解決方案的開發。Spring Boot提供了幾種通過RabbitMQ與AMQP協同工作的開箱即用的方式,包括spring-boot- sarter-amqp等各種Starter。
1.配置RabbitMQ
RabbitMQ的配置由外部配置屬性spring.rabbitmq.*來控制。例如,可以在application.properties中聲明以下部分。
spring. rabbi tmq. host=localhost
spring. rabbi tmq.port=5672
spring. rabbi tmq . username=admin
spring. rabbi tmq. password=secret
2.發送消息
Spring 的AmqpTemplate和AmqpAdmin是自動配置的,可以將它們直接自動裝配到自己的bean中。
import org.spr ingframework. amgp . core . AmqpAdmin;
import org. spr ingf ramework. amqp. core . AmqpTemplate;
import org. springframework.beans. factory . annotation. Autowired;
import org. springframework. stereotype. Component;
@Component
public class MyBean
private final AmqpAdmin amqpAdmin;
private final AmqpTemplate amqpTemplate;
@Autowired
public MyBean (AmqpAdmin amqpAdmin, AmqpTemplate amqpTemplate) {
this . amqpAdmin=amqpAdmin;
this . amqpTemplate=amqpTemplate;
}
}
3.接收消息
當Rabbit 的基礎架構存在時,可以使用@RabbitListener來注解bean,以創建偵聽器端點。如果沒有定義RabbitListenerContainerFactory,則會自動配置默認的SimpleRabitListenerContainerFactory。可以使用spring.rabbitmq.listener.type屬性切換到直接容器。如果MessageConverter或MessageRecoverer bean被定義,它們將自動關聯到默認工廠。
以下示例是在someQueue隊列上創建-一個偵聽器端點。
@Component
public class MyBean
@RabbitListener (queues=" someQueue")
public void processMessage (String content) {
//...
}
}
下篇文章給大家介紹數據持文化和實現熱插撥兩部分內容,歡迎大家來學習!!
也感謝大家支持!!
*請認真填寫需求信息,我們會在24小時內與您取得聯系。