日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java 架构师眼中的 HTTP 协议

發(fā)布時間:2024/3/12 java 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 架构师眼中的 HTTP 协议 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.


本文來自作者 張振華? GitChat 上分享 「Java 架構(gòu)師眼中的 HTTP 協(xié)議」,閱讀原文查看交流實(shí)錄。

編輯 | 哈比

HTTP 協(xié)議的基本內(nèi)容

· 什么是 HTTP 協(xié)議?

協(xié)議,是指計(jì)算機(jī)通信網(wǎng)絡(luò)中兩臺計(jì)算機(jī)之間進(jìn)行通信所必須共同遵守有規(guī)則的文本格式。

一旦有了協(xié)議,就可以使很多公司分工起來,有些公司做 Server 端,如 Tomcat,而有些公司就可以做瀏覽器了。這樣大家只要一套約定,彼此的通訊就會相互兼容。

什么是 HTTP?

HTTP 是基于 TCP/IP 的應(yīng)用層通信協(xié)議,它是客戶端和服務(wù)器之間相互通信的標(biāo)準(zhǔn)。它規(guī)定了如何在互聯(lián)網(wǎng)上請求和傳輸內(nèi)容。

通過應(yīng)用層協(xié)議,它只是一個規(guī)范了主機(jī)(客戶端和服務(wù)器)如何通信的抽象層,并且它本身依賴于 TCP/IP 來獲取客戶端和服務(wù)器之間的請求和響應(yīng)。

默認(rèn)的 TCP 端口是 80 端口,當(dāng)然,使用其他端口也是可以的。然而,HTTPS 使用的端口是 443 端口。

· HTTP 協(xié)議的簡單歷史

根據(jù)上圖,我們可將 HTTP 協(xié)議的發(fā)展歷程分為五個階段。

第一階段,1996 年之前。

第一版的 HTTP 文檔是 1991 年提出來的 HTTP/0.9,其主要特點(diǎn)有:

(1)它僅有一個 GET 方法。

(2)沒有 header 數(shù)據(jù)塊。

(3)必須以 HTML 格式響應(yīng)。

第二階段,HTTP/1.0 - 1996。

HTML 格式響應(yīng),HTTP/1.0 能夠處理其他的響應(yīng)格式,例如:圖像、視頻文件、純文本或其他任何的內(nèi)容類型(Content-Type 來區(qū)分)

它增加了更多的方法(即 POST 和 HEAD),請求 / 響應(yīng)的格式也發(fā)生了改變,請求和響應(yīng)中均加入了 HTTP 頭信息。

響應(yīng)數(shù)據(jù)還增加了狀態(tài)碼標(biāo)識,還介紹了字符集的支持、多部分發(fā)送、權(quán)限、緩存、內(nèi)容編碼等很多內(nèi)容。

HTTP/1.0 的主要缺點(diǎn)之一是,你不能在每個連接中發(fā)送多個請求。

也就是說,每當(dāng)客戶端要向服務(wù)器端請求東西時,它都會打開一個新的 TCP 連接,并且在這個單獨(dú)請求完成后,該連接就會被關(guān)閉。

每一次連接里面都包含了著名的三次握手協(xié)議。

于是有些 HTTP/1.0 的實(shí)現(xiàn)試圖通過引入一個新的頭信息 Connection: keep-alive,來解決這個問題。

第三個階段,HTTP/1.1 - 1999。

HTTP/1.0 發(fā)布之后,隨著 HTTP 開始普及之后,它的缺點(diǎn)也開始展現(xiàn)。

時隔三年,HTTP/1.1 便在 1999 年問世,它在之前的基礎(chǔ)上做了很多的改進(jìn)。主要內(nèi)容包含:

  • 新增的 HTTP 方法有 PUT、PATCH、HEAD、OPTIONS、DELETE。

  • 主機(jī)名標(biāo)識。在 HTTP/1.0 中,Host 頭信息不是必須項(xiàng),但 HTTP/1.1 中要求必須要有 Host 頭信息。

  • 持久性連接。正如前面所說,在 HTTP/1.0 中每個連接只有一個請求,且在這個請求完成后該連接就會被關(guān)閉,從而會導(dǎo)致嚴(yán)重的性能下降及延遲問題。HTTP/1.1 引入了對持久性連接的支持,例如:默認(rèn)情況下連接不會被關(guān)閉,在多個連續(xù)的請求下它會保存連接的打開狀態(tài)。想要關(guān)閉這些連接,需要將 Connection: close 加入到請求的頭信息中。客戶端通常會在最后一次請求中發(fā)送這個頭信息用來安全的關(guān)閉連接。

  • 管道機(jī)制。HTTP/1.1 也引入了對管道機(jī)制的支持,客戶端可以向服務(wù)器發(fā)送多個請求,而無需等待來自同一連接上的服務(wù)器響應(yīng),并且當(dāng)收到請求時服務(wù)器必須以相同的順序來響應(yīng)。但你可能會問客戶端是怎么知道第一個響應(yīng)下載完成和下一個響應(yīng)內(nèi)容開始的?要解決這個問題,必須要有 Content-Length 頭信息,客戶端可以用它來確定響應(yīng)結(jié)束,然后開始等待下一個響應(yīng)。

第四個階段,SPDY - 2009。

Google 走在前面,它開始試驗(yàn)一種可替換的協(xié)議來減少網(wǎng)頁的延遲,使得網(wǎng)頁加載更快、提升 Web 安全性。

2009 年,他們稱這種協(xié)議為 SPDY。SPDY 的功能包含多路復(fù)用、壓縮、優(yōu)先級、安全等。

2015 年,谷歌不想存在兩個相互競爭的標(biāo)準(zhǔn),因此他們決定把它合并到 HTTP 中成為 HTTP/2,同時放棄 SPDY。

第五個階段,HTTP/2 - 2015。

HTTP/2 是專為低延遲傳輸?shù)膬?nèi)容而設(shè)計(jì)。關(guān)鍵特征或與 HTTP / 1.1 舊版本的差異如下。

(1)二進(jìn)制協(xié)議。

HTTP/2 傾向于使用二進(jìn)制協(xié)議來減少 HTTP/1.x 中的延遲。二進(jìn)制協(xié)議更容易解析,而不具有像 HTTP/1.x 中那樣對人的可讀性。

HTTP/2 中的數(shù)據(jù)塊是幀和流。

HTTP 消息是由一個或多個幀組成的。有一個叫做 HEADERS 的幀存放元數(shù)據(jù),真正的數(shù)據(jù)是放在 DATA 幀中的。

幀類型定義在 the HTTP/2 specs(HTTP/2 規(guī)范),如 HEADERS、DATA、RST_STREAM、SETTINGS、PRIORITY 等。

每個 HTTP/2 請求和響應(yīng)都被賦予一個唯一的流 ID 且放入了幀中。幀就是一塊二進(jìn)制數(shù)據(jù)。

一系列幀的集合就稱為流。每個幀都有一個流 id,用于標(biāo)識它屬于哪一個流,每一個幀都有相同的頭。

同時,除了流標(biāo)識是唯一的,值得一提的是,客戶端發(fā)起的任何請求都使用奇數(shù)和服務(wù)器的響應(yīng)是偶數(shù)的流 id。

除了 HEADERS 和 DATA, 另外一個值得說一說幀類型是 RST_STREAM,它是一個特殊的幀類型,用于中止流,如客戶端發(fā)送這兒幀來告訴服務(wù)器我不再需要這個流了。

在 HTTP/1.1 中只有一種方式來實(shí)現(xiàn)服務(wù)器停止發(fā)送響應(yīng)給客戶端,那就是關(guān)閉連接引起延遲增加,因?yàn)楹罄m(xù)的請求就需要打開一個新的連接。

在 HTTP/2 中,客戶端可以使用 RST_FRAME 來停止接收指定的流而不關(guān)閉連接且還可以在此連接中接收其它流。

(2)多路復(fù)用。

由于 HTTP/2 現(xiàn)在是一個二進(jìn)制協(xié)議,且是使用幀和流來實(shí)現(xiàn)請求和響應(yīng)。

一旦 TCP 連接打開了,所有的流都通過這一連接來進(jìn)行異步的發(fā)送而不需要打開額外的連接。

反過來,服務(wù)器的響應(yīng)也是異步的方式,如響應(yīng)是無序的、客戶端使用流 id 來標(biāo)識屬于流的包。

這就解決了存在于 HTTP/1.x 中 head-of-line 阻塞問題,如客戶端將不必耗時等待請求,而其他請求將被處理。如下圖所示:


(3)HPACK 頭部壓縮。

它是一個單獨(dú)的用于明確優(yōu)化發(fā)送 Header RFC 的一部分。

它的本質(zhì)是,當(dāng)我們同一個客戶端不斷的訪問服務(wù)器時,在 header 中發(fā)送很多冗余的數(shù)據(jù),有時 cookie 就增大 header,且消耗帶寬和增加了延遲。

為了解決這個問題, HTTP/2 引入了頭部壓縮。與請求和響應(yīng)不同,header 不是使用 gzip 或 compress 等壓縮格式,它有不同的機(jī)制。

它使用了霍夫曼編碼和在客戶端和服務(wù)器維護(hù)的頭部表來消除重復(fù)的 headers(如 User Agent),在后續(xù)的請求中就只使用頭部表中引用。

它與 HTTP/1.1 中的一樣,不過增加了偽 header,如 :method、:scheme、:host 和:path。

(4)服務(wù)器推送。

在服務(wù)器端,Server Push 是 HTTTP/2 的另外一個重要功能。

我們知道,客戶端是通過請求來獲取資源的,它可以通過推送資源給客戶端而不需客戶端主動請求。

例如,瀏覽器載入了一個頁面,瀏覽器解析頁面時發(fā)現(xiàn)了需要從服務(wù)器端載入的內(nèi)容,接著它就發(fā)送一個請求來獲取這些內(nèi)容。

Server Push 允許服務(wù)器推送數(shù)據(jù)來減少客戶端請求。

它是如何實(shí)現(xiàn)的呢,服務(wù)器在一個新的流中發(fā)送一個特殊的幀 PUSH_PROMISE,來通知客戶端:“嘿,我要把這個資源發(fā)給你 ! 你就不要請求了。”

(5)請求優(yōu)先級。

客戶端可以在一個打開的流中在流的 HEADERS 幀中放入優(yōu)先級信息。在任何時間,客戶端都可以發(fā)送一個 PRIORITY 的幀來改變流的優(yōu)先級。

如果沒有優(yōu)先級信息,服務(wù)器就會異步的處理請求,比如無序處理。

如果流被賦予了優(yōu)先級,它就會基于這個優(yōu)先級來處理,由服務(wù)器決定需要多少資源來處理該請求。

(6)安全。

大家對 HTTP/2 是否強(qiáng)制使用安全連接(通過 TLS)進(jìn)行了充分的討論。最后的決定是不強(qiáng)制使用。

然而,大多數(shù)廠商表示,他們將只支持基于 TLS 的 HTTP/2。所以,盡管 HTTP/2 規(guī)范不需要加密,但它已經(jīng)成為默認(rèn)的強(qiáng)制執(zhí)行的。

在這種情況下,基于 TLS 實(shí)現(xiàn)的 HTTP/2 需要的 TLS 版本最低要求是 1.2。 因此必須有最低限度的密鑰長度、臨時密鑰等。

通過開發(fā)者工具我們看一下 Google 的請求協(xié)議。


而我們大多數(shù)的網(wǎng)站的協(xié)議的版本都是 HTTP 1.1。

HTTP 協(xié)議的具體內(nèi)容

而我們平時老生常談的 HTTP 的協(xié)議大都是指的是 HTTP 1.1 協(xié)議的內(nèi)容,接下去我們一起看一下 HTTP 1.1 協(xié)議的結(jié)構(gòu)。如下圖所示。

接下來,我將通過四部分大概介紹一下 HTTP 協(xié)議的基本內(nèi)容。

1.URL & URI

schema://host[:port#]/path/.../[;url-params][?query-string][#anchor]

URL(Uniform Resource Locator)主要包括以下幾部分。

  • scheme:指定低層使用的協(xié)議,一般是 HTTP,如果強(qiáng)調(diào)安全的話可以是 HTTPS。

  • host:HTTP 服務(wù)器的 IP 地址或者域名。

  • port:HTTP 服務(wù)器的默認(rèn)端口是 80,這種情況下端口號可以省略。如果使用了別的端口,必須指明。

  • path:訪問資源的路徑。

  • url-params:URL 的參數(shù)。

  • query-string:發(fā)送給 HTTP 服務(wù)器的數(shù)據(jù)。

  • anchor:錨。

URI,在 Java 的 Servlet 中指的是 resource path 部分。

2. 請求方法 Method

主要包括以下幾種請求方法。

  • GET:向指定的資源發(fā)出 “顯示” 請求。使用 GET 方法應(yīng)該只用在讀取數(shù)據(jù),而不應(yīng)當(dāng)被用于產(chǎn)生 “副作用” 的操作中,例如在 Web Application 中。其中一個原因是 GET 可能會被網(wǎng)絡(luò)蜘蛛等隨意訪問。

  • POST:向指定資源提交數(shù)據(jù),請求服務(wù)器進(jìn)行處理(例如提交表單或者上傳文件)。數(shù)據(jù)被包含在請求本文中。這個請求可能會創(chuàng)建新的資源或修改現(xiàn)有資源,或二者皆有。

  • PUT:向指定資源位置上傳其最新內(nèi)容。

  • DELETE:請求服務(wù)器刪除 Request-URI 所標(biāo)識的資源。

  • OPTIONS:這個方法可使服務(wù)器傳回該資源所支持的所有 HTTP 請求方法。用 “*” 來代替資源名稱,向 Web 服務(wù)器發(fā)送 OPTIONS 請求,可以測試服務(wù)器功能是否正常運(yùn)作。

  • HEAD:與 GET 方法一樣,都是向服務(wù)器發(fā)出指定資源的請求。只不過服務(wù)器將不傳回資源的本文部分。它的好處在于,使用這個方法可以在不必傳輸全部內(nèi)容的情況下,就可以獲取其中 “關(guān)于該資源的信息”(元信息或稱元數(shù)據(jù))

  • TRACE:回顯服務(wù)器收到的請求,主要用于測試或診斷。

  • CONNECT:HTTP/1.1 協(xié)議中預(yù)留給能夠?qū)⑦B接改為渠道方式的代理服務(wù)器。通常用于 SSL 加密服務(wù)器的鏈接(經(jīng)由非加密的 HTTP 代理服務(wù)器)

Method 名稱是區(qū)分大小寫的。

當(dāng)某個請求所針對的資源不支持對應(yīng)的請求方法的時候,服務(wù)器應(yīng)當(dāng)返回狀態(tài)碼 405(Method Not Allowed),當(dāng)服務(wù)器不認(rèn)識或者不支持對應(yīng)的請求方法的時候,應(yīng)當(dāng)返回狀態(tài)碼 501(Not Implemented)

3.HTTP 之狀態(tài)碼

狀態(tài)代碼有三位數(shù)字組成,第一個數(shù)字定義了響應(yīng)的類別,共分五種類別:

  • 1xx:指示信息—表示請求已接收,繼續(xù)處理。

  • 2xx:成功—表示請求已被成功接收、理解、接受。

  • 3xx:重定向—要完成請求必須進(jìn)行更進(jìn)一步的操作。

  • 4xx:客戶端錯誤—請求有語法錯誤或請求無法實(shí)現(xiàn)。

  • 5xx:服務(wù)器端錯誤—服務(wù)器未能實(shí)現(xiàn)合法的請求。

常見狀態(tài)碼有:

200 OK ? ? ? ? ? ? ? ? ? ? ? ?// 客戶端請求成功 400 Bad Request ? ? ? ? ? ? ? // 客戶端請求有語法錯誤,不能被服務(wù)器所理解 401 Unauthorized ? ? ? ? ? ? ?// 請求未經(jīng)授權(quán),這個狀態(tài)代碼必須和 WWW-Authenticate 報(bào)頭域一起使用 403 Forbidden ? ? ? ? ? ? ? ? // 服務(wù)器收到請求,但是拒絕提供服務(wù) 404 Not Found ? ? ? ? ? ? ? ? // 請求資源不存在,eg:輸入了錯誤的 URL 500 Internal Server Error ? ? // 服務(wù)器發(fā)生不可預(yù)期的錯誤 503 Server Unavailable ? ? ? ?// 服務(wù)器當(dāng)前不能處理客戶端的請求,一段時間后可能恢復(fù)正常

4. 請求體 & 響應(yīng)體

請求體 & 響應(yīng)體,這個沒有特殊規(guī)定,需要配合不同的 Content-Type 來使用。

唯一需要注意的是 multipart/form-data、application/x-www-from-urlencoded、raw、binary 的區(qū)別。

(1)multipart/form-data

它將表單的數(shù)據(jù)組織成 Key-Value 形式,用分隔符 boundary(boundary 可任意設(shè)置)處理成一條消息。

由于有 boundary 隔離,所以當(dāng)即上傳文件,又有參數(shù)的時候,必須要用這種 ?content-type 類型。如下圖所示:

(2)x-www-form-urlencoded

即 application/x-www-from-urlencoded,將表單內(nèi)的數(shù)據(jù)轉(zhuǎn)換為 Key-Value。這種和 Get 方法把參數(shù)放在 URL 后面一樣的想過,這種不能文件上傳。

(3)raw

可以上傳任意格式的 “文本”,可以上傳 Text、JSON、XML、HTML 等。

(4)binary

即 Content-Type:application/octet-stream,只可以上傳二進(jìn)制數(shù)據(jù)流,通常用來上傳文件。由于沒有鍵值,所以一次只能上傳一個文件。

(5)Header

HTTP 消息的 Headers 共分為三種,分別是 General Headers、Entity Headers、Request/Response Headers。

  • General Headers

我把被 Request 和 Response 共享的 Headers 成為 General Headers,具體有:

general-header = Cache-Control| Connection
? ? ? ? ? ? ? | Date
? ? ? ? ? ? ? | Pragma
? ? ? ? ? ? ? | Trailer
? ? ? ? ? ? ? | Transfer-Encoding
? ? ? ? ? ? ? | Upgrade
? ? ? ? ? ? ? | Via
? ? ? ? ? ? ? | Warning

其中,Cache-Control 指定請求和響應(yīng)遵循的緩存機(jī)制;

Connection 允許客戶端和服務(wù)器指定與請求 / 響應(yīng)連接有關(guān)的選項(xiàng);

Date 提供日期和時間標(biāo)志,說明報(bào)文是什么時間創(chuàng)建的;

Pragma 頭域用來包含實(shí)現(xiàn)特定的指令,最常用的是 Pragma:no-cache;

Trailer,如果報(bào)文采用了分塊傳輸編碼 (chunked transfer encoding) 方式,就可以用這個首部列出位于報(bào)文拖掛(trailer)部分的首部集合;

Transfer-Encoding 告知接收端為了保證報(bào)文的可靠傳輸,對報(bào)文采用了什么編碼方式;

Upgrade 給出了發(fā)送端可能想要 “升級” 使用的新版本和協(xié)議;

Via 顯示了報(bào)文經(jīng)過的中間節(jié)點(diǎn)(代理,網(wǎng)嘎 un)

  • Entity Headers

Entity Headers 主要用來描述消息體(message body)的一些元信息,具體有:

entity-header ?= Allow
? ? ? ? ? ? ? | Content-Encoding
? ? ? ? ? ? ? | Content-Language
? ? ? ? ? ? ? | Content-Length
? ? ? ? ? ? ? | Content-Location
? ? ? ? ? ? ? | Content-MD5
? ? ? ? ? ? ? | Content-Range
? ? ? ? ? ? ? | Content-Type
? ? ? ? ? ? ? | Expires
? ? ? ? ? ? ? | Last-Modified

其中,以 Content 為前綴的 Headers 主要描述了消息體的結(jié)構(gòu)、大小、編碼等信息,Expires 描述了 Entity 的過期時間,Last-Modified 描述了消息的最后修改時間。

  • Request/Response Headers

Request-Line 是 Request 消息體的第一部分,其具體定義如下:

Request-Line = Method SP URI SP HTTP-Version CRLF Method = "OPTIONS"| "HEAD"
? ? ? | "GET"
? ? ? | "POST"
? ? ? | "PUT"
? ? ? | "DELETE"
? ? ? | "TRACE"

其中 SP 代表字段的分隔符,HTTP-Version 一般就是 “http/1.1”,后面緊接著是一個換行。

在 Request-Line 后面緊跟著的就是 Headers。我們在上面已經(jīng)介紹了 General Headers 和 Entity Headers,下面便是 Request Headers 的定義。

request-header = Accept
? ? ? ? ? ? ?| Accept-Charset
? ? ? ? ? ? ?| Accept-Encoding
? ? ? ? ? ? ?| Accept-Language
? ? ? ? ? ? ?| Authorization
? ? ? ? ? ? ?| Expect
? ? ? ? ? ? ?| From
? ? ? ? ? ? ?| Host
? ? ? ? ? ? ?| If-Match
? ? ? ? ? ? ?| If-Modified-Since
? ? ? ? ? ? ?| If-None-Match
? ? ? ? ? ? ?| If-Range
? ? ? ? ? ? ?| If-Unmodified-Since
? ? ? ? ? ? ?| Max-Forwards
? ? ? ? ? ? ?| Proxy-Authorization
? ? ? ? ? ? ?| Range
? ? ? ? ? ? ?| Referer
? ? ? ? ? ? ?| TE
? ? ? ? ? ? ?| User-Agent

Request Headers 扮演的角色其實(shí)就是一個 Request 消息的調(diào)節(jié)器。

需要注意的是若一個 Headers 名稱不在上面列表中,則默認(rèn)當(dāng)做 Entity Headers 的字段。

前綴為 Accept 的 Headers 定義了客戶端可以接受的媒介類型、語言和字符集等。

From、Host、Referer 和 User-Agent 詳細(xì)定義了客戶端如何初始化 Request。

前綴為 If 的 Headers 規(guī)定了服務(wù)器只能返回符合這些描述的資源,若不符合,則會返回 304 Not Modified。

Request Body,若 Request-Line 中的 Method 為 GET,請求中不包含消息體,若為 POST,則會包含消息體。

一個具體的 Request 消息實(shí)例,如下。

GET /articles/http-basics HTTP/1.1 Host: www.articles.com Connection: keep-alive Cache-Control: no-cache Pragma: no-cache Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

  • Response 消息體

Response 消息格式和 Request 類似,也分為三部分,即 Response-Line、Response Headers、Response Body。

Response-Line 具體定義如下:

Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF HTTP-Version 字段值一般為 HTTP/1.1 Status-Code 前面已經(jīng)討論過了 Reason-Phrase 是對 status code 的具體描述

一個最常見的 Response 響應(yīng)為:

HTTP/1.1 200 OK

Response Headers 的定義如下。

response-header = Accept-Ranges
? ? ? ? ? ? ? | Age
? ? ? ? ? ? ? | ETag
? ? ? ? ? ? ? | Location
? ? ? ? ? ? ? | Proxy-Authenticate
? ? ? ? ? ? ? | Retry-After
? ? ? ? ? ? ? | Server
? ? ? ? ? ? ? | Vary
? ? ? ? ? ? ? | WWW-Authenticate

其中,Age 表示消息自 server 生成到現(xiàn)在的時長,單位是秒;ETag 是對 Entity 進(jìn)行 MD5 hash 運(yùn)算的值,用來檢測更改;Location 是被重定向的 URL;Server 表示服務(wù)器標(biāo)識。

Http 更加詳細(xì)的介紹,請參考?http://www.runoob.com/http/http-status-codes.html。

架構(gòu)師關(guān)注 HTTP 協(xié)議的重點(diǎn)

HTTP 協(xié)議內(nèi)容其實(shí)也挺多的,架構(gòu)師其實(shí)也應(yīng)該有重點(diǎn),哪些是我們必須重點(diǎn)關(guān)注的,心里要清楚。

· 采用哪個 HTTP 協(xié)議版本及其 Java 里面如何配置

1.Tomcat 的原始配置在 server.xml 里面。

<Connector port="8443"
protocol="org.apache.coyote.http11.Http11AprProtocol" ? ? ? ? ? ? ? maxThreads="150" SSLEnabled="true" > ? ? ? ? ? <UpgradeProtocol
className="org.apache.coyote.http2.Http2Protocol" /> ? ? ? ? ? <SSLHostConfig> ? ? ? ? ? ? ? <Certificate certificateKeyFile="conf/localhost-rsa-key.pem" ? ? ? ? ? ? ? ? ? ? ? ? ?certificateFile="conf/localhost-rsa-cert.pem" ? ? ? ? ? ? ? ? ? ? ? ? ?certificateChainFile="conf/localhost-rsa-chain.pem" ? ? ? ? ? ? ? ? ? ? ? ? ?type="RSA" /> ? ? ? ? ? </SSLHostConfig></Connector>

2.Spring boot2.0 項(xiàng)目的配置方法。

只需要在 properties 里面選擇如下配置即可。

server.ssl.enabled=true server.ssl.****// 等等 server.http2.enabled=true server.tomcat.protocol-header-https-value=https

需要注意的是一般 HTTP 2 的使用都要伴隨著證書。詳細(xì)的配置直接參考 ServerProperties 類里面的具體描述即可。

· HTTPS 配置注意事項(xiàng)

一般很少針對單個項(xiàng)目去設(shè)置的,一般都是通過開源的云如 ali、asw 里面的 SLB 配置 HTTP2 和證書,在網(wǎng)關(guān)那層統(tǒng)一做掉。

客戶端一般是各個瀏覽器或者 App 的瀏覽器內(nèi)核庫來支持的。其實(shí)也很少需要開發(fā)來關(guān)心具體如何按照 HTTP2 來實(shí)現(xiàn)一些代碼邏輯。

· 緩存機(jī)制 HTTP 緩存

1. 如何緩存

降低網(wǎng)絡(luò)上發(fā)送 HTTP 請求的次數(shù),這里采用 “過期” 機(jī)制。

HTTP 服務(wù)器通過兩種實(shí)體頭(Entity-Header)來實(shí)現(xiàn) “過期” 機(jī)制:Expires 頭和 Cache-Control 頭的 max-age 子項(xiàng)。

Expires/Cache-Control 控制瀏覽器是否直接從瀏覽器緩存取數(shù)據(jù)還是重新發(fā)請求到服務(wù)器取數(shù)據(jù)。

只是 Cache-Control 比 Expires 可以控制的多一些,而且 Cache-Control 會重寫 Expires 的規(guī)則。

降低網(wǎng)絡(luò)上完整回復(fù) HTTP 請求包的次數(shù),這里采用 “確證” 機(jī)制。

HTTP 服務(wù)器通過兩種方式實(shí)現(xiàn) “確證” 機(jī)制:ETag 以及 Last-Modified。

2. 相關(guān)的 Header

主要包括以下幾個。

  • Cache-Control

常用的值有:

(1)max-age(單位為 s)指定設(shè)置緩存最大的有效時間,定義的是時間長短。

當(dāng)瀏覽器向服務(wù)器發(fā)送請求后,在 max-age 這段時間里瀏覽器就不會再向服務(wù)器發(fā)送請求了。

(2)s-maxage(單位為 s)同 max-age,只用于共享緩存(比如 CDN 緩存),也就是說 max-age 用于普通緩存,而 s-maxage 用于代理緩存。

如果存在 s-maxage,則會覆蓋掉 max-age 和 Expires header。

(3)public 指定響應(yīng)會被緩存,并且在多用戶間共享。如果沒有指定 public 還是 private,則默認(rèn)為 public。

(4)private 響應(yīng)只作為私有的緩存,不能在用戶間共享。如果要求 HTTP 認(rèn)證,響應(yīng)會自動設(shè)置為 private。

(5)no-cache 指定不緩存響應(yīng),表明資源不進(jìn)行緩存,比如,設(shè)置了 no-cache 之后并不代表瀏覽器不緩存,而是在緩存前要向服務(wù)器確認(rèn)資源是否被更改。

因此有的時候只設(shè)置 no-cache 防止緩存還是不夠保險,還可以加上 private 指令,將過期時間設(shè)為過去的時間。

(6)no-store 表示絕對禁止緩存。一看就知道,如果用了這個命令,當(dāng)然就是不會進(jìn)行緩存啦!每次請求資源都要從服務(wù)器重新獲取。

(7)must-revalidate 指定如果頁面是過期的,則去服務(wù)器進(jìn)行獲取。這個指令并不常用,就不做過多的討論了。

  • Expires

緩存過期時間,用來指定資源到期的時間,是服務(wù)器端的具體時間點(diǎn)。

也就是說,Expires=max-age + 請求時間,需要和 Last-modified 結(jié)合使用。

但在上面我們提到過 cache-control 的優(yōu)先級更高。

Expires 是 Web 服務(wù)器響應(yīng)消息頭字段,在響應(yīng) HTTP 請求時告訴瀏覽器在過期時間前瀏覽器可以直接從瀏覽器緩存取數(shù)據(jù),而無需再次請求。

  • Last-modified

服務(wù)器端文件的最后修改時間,需要和 cache-control 共同使用,是檢查服務(wù)器端資源是否更新的一種方式。

當(dāng)瀏覽器再次進(jìn)行請求時,會向服務(wù)器傳送 If-Modified-Since 報(bào)頭,詢問 Last-Modified 時間點(diǎn)之后資源是否被修改過。

如果沒有修改,則返回碼為 304,使用緩存;

如果修改過,則再次去服務(wù)器請求資源,返回碼和首次請求相同為 200,資源為服務(wù)器最新資源。

  • Etag

根據(jù)實(shí)體內(nèi)容生成一段 hash 字符串,標(biāo)識資源的狀態(tài),由服務(wù)端產(chǎn)生。瀏覽器會將這串字符串傳回服務(wù)器,驗(yàn)證資源是否已經(jīng)修改。

為什么要使用 Etag 呢 ?Etag 主要為了解決 Last-Modified 無法解決的一些問題。

一些文件也許會周期性的更改,但是它的內(nèi)容并不改變(僅僅改變的修改時間),這個時候我們并不希望客戶端認(rèn)為這個文件被修改了,而重新 Get。

某些文件修改非常頻繁,比如在秒以下的時間內(nèi)進(jìn)行修改(比方說 1s 內(nèi)修改了 N 次),If-Modified-Since 能檢查到的粒度是 s 級的,這種修改無法判斷(或者說 UNIX 記錄 MTIME 只能精確到秒)

某些服務(wù)器不能精確的得到文件的最后修改時間。

緩存過程如下圖所示:

· Session 與 Cookie 必知必會

很好的解決了 HTTP 通訊中狀態(tài)問題,但其本身也存在一些問題,比如:

  • 客戶端存儲,可能會被修改或刪除。

  • 發(fā)送請求時,Cookie 會被一起發(fā)送到服務(wù)器,當(dāng) Cookie 數(shù)據(jù)量較大時也會帶來額外的請求數(shù)據(jù)量。

  • 客戶端對 Cookie 數(shù)量及大小有一定的限制,Session 解決了 Cookie 的一些缺點(diǎn)。Session 同樣是為了記錄用戶狀態(tài),對于每個用戶來說都會有相應(yīng)的一個狀態(tài)值保存在服務(wù)器中,而只在客戶端記錄一個 sessionID 用于區(qū)分是哪個用戶的 Session。

與 Cookie 相比,Session 有一定的優(yōu)勢,如:

  • Session 值存儲在服務(wù)器,相對來說更安全。

  • 客戶端發(fā)送給服務(wù)器的只有一個 sessionID,數(shù)據(jù)量更小。Session 同樣需要在客戶端存儲一個 sessionID。可以這個值存儲在 Cookie,每次發(fā)送請求時通過 Cookie 請求頭將其發(fā)送到服務(wù)器;也可以不使用 Cookie,而將 sessionID 作為一個額外的請求參數(shù),通過 URL 或請求體發(fā)送到服務(wù)器。

基于 Cookie 實(shí)現(xiàn) Session 的實(shí)現(xiàn)原理如下圖:

由上可見,基于 Cookie 實(shí)現(xiàn) Session 時,其本質(zhì)上還是在客戶端保存一個 Cookie 值。

這個值就是 sessionID,sessionID 的名稱也可按需要設(shè)置,為保存安全,其值也可能會在服務(wù)器端做加密處理。

服務(wù)器在收到 sessionID 后,就可以對其解密及查找對應(yīng)的用戶信息等。

· 協(xié)議格式如何統(tǒng)一(見文章后面內(nèi)容)

Spring 對 HTTP 協(xié)議的支持

我為什么想提一下這個呢,我看到太多的開發(fā)者遇到 HTTP 協(xié)議都喜歡自定義變量,自定義類,其實(shí)完全沒有必要。且看下面的分析。

· Spring MVC Web

在 spring-web**.jar 里面我們可以找到如下幾個類:

需要我們重點(diǎn)關(guān)注的有 HttpStatus、MediaType 等。

Spring web bind 中對應(yīng)的注解,如下圖所示:

上面是一些主要的(需要注意的是 @RequestParam、@PostMapping、@**Mapping 與我們上面的 HttpMethod 相對應(yīng)。

而里面還有 Headers、Consumes 和 produces 等參數(shù)來確定一些 Mapping 的條件),下面的可以根據(jù)需要查看源碼里面有哪些注解。

· Spring Data Rest

Spring Data Rest 是基于 Spring Data repositories,分析實(shí)體之間的關(guān)系。為我們生成 Hypermedia API(HATEOAS) 風(fēng)格的 Http Restful API 接口。

Spring Data REST 通過構(gòu)建在 Spring Data repositories 之上,自動將其導(dǎo)出為 REST 資源的 api,減少了大量重復(fù)代碼和無聊的樣板代碼。

它利用超媒體來允許客戶端查找存儲庫暴露的功能,并將這些資源自動集成到相關(guān)的超媒體功能中。

Spring Data REST 本身就是一個 Spring MVC 應(yīng)用程序,它的設(shè)計(jì)方式應(yīng)該是盡可能少的集成到現(xiàn)有的 Spring MVC 應(yīng)用程序中。

現(xiàn)有的(或?qū)淼?#xff09;服務(wù)層可以與 Spring Data REST 一起運(yùn)行,只有較小的考慮。

· Spring RestTemplate 的實(shí)際使用

Spring RestTemplate 是 Spring 提供的用于訪問 Rest 服務(wù)的客戶端,RestTemplate 提供了多種便捷訪問遠(yuǎn)程 HTTP 服務(wù)的方法,能夠大大提高客戶端的編寫效率。

簡單例子,如下。

RestTemplate restTemplate = new RestTemplate(); String fooResourceUrl = "http://localhost:8080/spring-rest/foos"; ResponseEntity<String> response =
restTemplate.getForEntity(fooResourceUrl + "/1", String.class); assertThat(response.getStatusCode(), equalTo(HttpStatus.OK));

更詳盡例子,如下。

/** * 發(fā)送一個 get 請求,并接受封裝成 map */ @Test public void restTemplateMap() {RestTemplate restTemplate = new RestTemplate();Map map=restTemplate.getForObject("https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=ACCESS_TOKEN",Map.class);System.out.println(map.get("errmsg")); }/** * 發(fā)送一個 get 請求,并接受封裝成 string */ @Test public void restTemplateString() {RestTemplate restTemplate = new RestTemplate();String str=restTemplate.getForObject("https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=ACCESS_TOKEN",String.class);System.out.println(str); } /** * 添加消息頭 */ @Test public void httpHeaders() {final String uri = "https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=ACCESS_TOKEN";RestTemplate restTemplate = new RestTemplate();HttpHeaders headers = new HttpHeaders();headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);ResponseEntity<String> result = restTemplate.exchange(uri, HttpMethod.GET, entity, String.class);System.out.println(result); }

我們在實(shí)際工作中會覆蓋默認(rèn)的 RestTemplate。

/*** 替代默認(rèn)的 SimpleClientHttpRequestFactory* 設(shè)置超時時間重試次數(shù)* 還可以設(shè)置一些攔截器以便監(jiān)控** @return*/ @Bean public RestTemplate restTemplate() {// 生成一個設(shè)置了連接超時時間、請求超時時間、異常重試次數(shù) 3 次 ? ?RequestConfig config = RequestConfig.custom().setConnectionRequestTimeout(10000).setConnectTimeout(10000).setSocketTimeout(30000).build(); // 實(shí)際工作中,這個地方還會加上 filter 來抓取每次 restTemplate 的日志信息。 ? ?HttpClientBuilder builder = HttpClientBuilder.create().setDefaultRequestConfig(config).setRetryHandler(new DefaultHttpRequestRetryHandler(3, false)); ? ?HttpClient httpClient = builder.build(); ? ?ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); ? ?RestTemplate restTemplate = new RestTemplate(requestFactory); ? ?return restTemplate; }

使用的地方會變成如下即可。

@Autowired public RestTemplate restTemplate;

· Spring Data Jpa

隨著使用 Spring Data Jpa 的人越來越多,它里面也對 Spring Web 做了很好的支持。

我們可以重點(diǎn)看一下 Pageable 和 Page,以及 PageImpl 和 PageRequest 對分頁和排序做了很好的封裝,及其返回的 JSON 格式也做了很好的約定。

· Spring Cloud 中的知識點(diǎn)

Spring Cloud 的微服務(wù)管理都是基于 HTTP 協(xié)議的 Rest 風(fēng)格的 API 來管理的,所以我們詳細(xì)了解 HTTP 協(xié)議還是非常有必要的。

JSON API

我們都知道了約定的好處。如果你和你的團(tuán)隊(duì)曾經(jīng)爭論過使用什么方式構(gòu)建合理 JSON 響應(yīng)格式, 那么 JSON API 就是你的 anti-bikeshedding 武器。

通過遵循共同的約定,可以提高開發(fā)效率,利用更普遍的工具,可以是你更加專注于開發(fā)重點(diǎn):你的程序。

點(diǎn)擊?http://jsonapi.org 訪問 JSON API 官方。

(1)JSON API 介紹

JSON API 是數(shù)據(jù)交互規(guī)范,用以定義客戶端如何獲取與修改資源,以及服務(wù)器如何響應(yīng)對應(yīng)請求。

JSON API 設(shè)計(jì)用來最小化請求的數(shù)量,以及客戶端與服務(wù)器間傳輸?shù)臄?shù)據(jù)量。在高效實(shí)現(xiàn)的同時,無需犧牲可讀性、靈活性和可發(fā)現(xiàn)性。

JSON API 需要使用 JSON API 媒體類型(application/vnd.api+json)進(jìn)行數(shù)據(jù)交互。

JSON API 服務(wù)器支持通過 GET 方法獲取資源。而且必須獨(dú)立實(shí)現(xiàn) HTTP POST,PUT 和 DELETE 方法的請求響應(yīng),以支持資源的創(chuàng)建、更新和刪除。

JSON API 服務(wù)器也可以選擇性支持 HTTP PATCH 方法 [RFC5789] 和 JSON Patch 格式 [RFC6902],進(jìn)行資源修改。

JSON Patch 支持是可行的,因?yàn)槔碚撋蟻碚f,JSON API 通過單一 JSON 文檔,反映域下的所有資源,并將 JSON 文檔作為資源操作介質(zhì)。

在文檔頂層,依據(jù)資源類型分組。每個資源都通過文檔下的唯一路徑辨識。

(2)規(guī)則約定

文檔中的關(guān)鍵字 MUST、MUST NOT、REQUIRED、SHALL、SHALL NOT、SHOULD、 SHOULD NOT、RECOMMENDED、MAY 和 OPTIONAL。依據(jù) RFC 2119 [RFC2119] 規(guī)范解釋。

(3)內(nèi)容約定

客戶端職責(zé),即客戶端必須在包含 Content-Type: application/vnd.api+json 頭并且不包含媒體類型參數(shù)的請求文檔中發(fā)送所有 JSON API 數(shù)據(jù)。

在 Accept 頭中包含 JSON API 媒體類型并且不包含媒體類型參數(shù)的客戶端必須在 Accept 頭中指定媒體類型至少一次。

客戶端必須忽略任何從響應(yīng)文檔的 Content-Type 頭中獲取的 application/vnd.api+json 媒體類型參數(shù)。

服務(wù)器職責(zé),即服務(wù)器必須在包含 Content-Type: application/vnd.api+json 頭并且不包含媒體類型參數(shù)的請求文檔中發(fā)送所有 JSON API 數(shù)據(jù)。

如果接收到一個用任何媒體類型參數(shù)指定 Content-Type: application/vnd.api+json 頭的請求,服務(wù)器必須返回一個 415 Unsupported Media Type 狀態(tài)碼響應(yīng)。

如果接收到一個在 Accept 頭中包含任何 JSON API 媒體類型并且所有實(shí)體都以媒體類型參數(shù)更改的請求,服務(wù)器必須返回一個 406 Not Acceptable 狀態(tài)碼響應(yīng)。

(4)文檔結(jié)構(gòu)

我們將描述 JSON API 文檔結(jié)構(gòu),通過媒體類型?application/vnd.api+json 標(biāo)示。

JSON API 文檔使用 JavaScript 對象(JSON)[RFC4627] 定義。

盡管同種媒體類型用以請求和響應(yīng)文檔,但某些特性只適用于其中一種。差異在下面呈現(xiàn)。

除非另有說明,根據(jù)本規(guī)范定義的對象都不應(yīng)該包含任何其他鍵。

客戶端和服務(wù)器實(shí)現(xiàn)必須忽略本規(guī)范未指定的鍵。

(5)Top Level

JSON 對象必須位于每個 JSON API 文檔的根級。這個對象定義文檔的 “top level”。

文檔必須包含以下至少一種 top-level 鍵。

  • data: 文檔的”primary data”。

  • errors: 錯誤對象列表。

  • meta: 包含非標(biāo)準(zhǔn)元信息的元對象。

data 鍵和 errors 鍵不能再一個文檔中同時存在。

文檔可能包含以下任何 top-level 鍵。

  • jsonapi: 描述服務(wù)器實(shí)現(xiàn)的對象。

  • links: 與 primary data 相關(guān)的鏈接對象。

  • include: 與 primary data 或其他資源相關(guān)的資源對象(included resources)列。

如果文檔不包含 top-level data 鍵,included 鍵也不應(yīng)該出現(xiàn)。

文檔的 top-level 鏈接對象可能包含以下鍵。

  • self: 生成當(dāng)前響應(yīng)文檔的鏈接。

  • related: 當(dāng) primary data 代表資源關(guān)系時,表示相關(guān)資源鏈接。

  • Primary data 的分頁鏈接。

文檔中的 “primary data” 代表一個請求所要求的資源或資源集合。

Primary data 必須是以下列舉的一種。

  • 如果請求要求單一資源,應(yīng)該是一個單一資源對象,或一個單一資源標(biāo)識符,或 null。

  • 如果請求要求資源集合,應(yīng)該是一個資源對象列表,或一個空列表 ([])。

例如,以下 primary data 表示一個單一資源對象。

{"data": {"type": "articles", ? ?"id": "1", ? ?"attributes": { ? ? ?// ... this article's attributes ? ?}, ? ?"relationships": { ? ? ?// ... this article's relationships ? ?}} }

以下 primary data 表示一個指向同樣資源的單一資源標(biāo)識符。

{ ? ?"data": { ? ? ?"type": "articles", ? ? ?"id": "1" ? ?} }

即使只包含一個元素或?yàn)榭?#xff0c;資源的一個邏輯集合也必須表示為一個列表。

資源對象,即 JSON API 文檔中的 “Resuorce objects”,代表資源。

一個資源對象必須至少包含以下 top-level 鍵。

  • id

  • `type’

例外,當(dāng)資源對象來自客戶端并且代表一個將要在服務(wù)器創(chuàng)建的新資源時,id 鍵不是必須的。

此外,資源對象可能包含以下 top-level 鍵。

  • ‘a(chǎn)ttribute’: 屬性對象代表資源的某些數(shù)據(jù)。

  • relationshiops: 關(guān)聯(lián)對象描述該資源與其他 JSON API 資源之間的關(guān)系。

  • links: 鏈接資源包含與資源相關(guān)的鏈接。

  • meta: 元數(shù)據(jù)資源包含與資源對象相關(guān)的非標(biāo)準(zhǔn)元信息,這些信息不能被作為屬性或關(guān)聯(lián)對象表示。

一篇文獻(xiàn)(即一個 “文獻(xiàn)” 類型的資源)在文檔中這樣表示:

{ ?"type": "articles","id": "1","attributes": {"title": "Rails is Omakase"},"relationships": {"author": {"links": {"self": "/articles/1/relationships/author","related": "/articles/1/author" ? ? ?}, ? ? ?"data": { "type": "people", "id": "9" }}} }

標(biāo)識符,即每個資源對象包含一個 id 鍵和一個 type 鍵。id 鍵和 typ e 鍵的值必須是字符串類型。

對于每一個既定 API,每個資源對象的 type 和 id 對必須定義一個單獨(dú)且唯一的資源(由一個或多個但行為表現(xiàn)為一個服務(wù)器的服務(wù)器控制的 URI 集合構(gòu)成一個 API)

type 鍵用于描述共享相同屬性和關(guān)聯(lián)的資源對象。type 鍵的值必須與遵循鍵名稱相同的約束條件。

字段,即資源對象的屬性和關(guān)聯(lián)被統(tǒng)稱為 “fields”。

一個資源對象的所有字段必須與 type 和 id 在同一命名空間中。即一個資源不能擁有名字相同的屬性與關(guān)聯(lián),也不能擁有被命名為 type 或 id 的屬性和關(guān)聯(lián)。

屬性,即 attribute,鍵的值必須是一個對象(一個 “attributes object”)。屬性對象的鍵(“attributes”)代表與資源對象中定義的與其有關(guān)的信息。

屬性可以包含任何合法 JSON 值。JSON 對象和列表涉及的復(fù)雜數(shù)據(jù)結(jié)構(gòu)可以作為屬性的值。

但是一個組成或被包含于屬性中的對象不能包含 relationships 或 links 鍵,因?yàn)檫@些鍵為此規(guī)范未來的用途所預(yù)留。

雖然一些 has-one 關(guān)系的外鍵(例如 author_id)被在內(nèi)部與其他將要在資源對象中表達(dá)的信息一起儲存,但是這些鍵不能作為屬性出現(xiàn)。

關(guān)聯(lián),即 relationships,鍵的值必須是一個對象(“relationships object”)

關(guān)聯(lián)對象(“relationships”)的鍵表示在資源對象中定義的與其相關(guān)的其他資源對象。

關(guān)聯(lián)可以是單對象關(guān)聯(lián)或多對象關(guān)聯(lián)。

一個 “relationship object” 必須包含以下至少一種鍵:

  • links: 一個鏈接對象至少包含以下一種鍵:

  • self: 指向關(guān)聯(lián)本身的鏈接(“relationship link”)。此鏈接允許客戶端直接修改關(guān)聯(lián)。例如,通過一個 articale 的關(guān)聯(lián) URL 移除一個 author 將會解除一個人與 article 的關(guān)系,而不需要刪除這個 people 資源本身。獲取成功后,這個鏈接將返回一個相關(guān)資源之間的連接,將其作為 primary data(見獲取關(guān)聯(lián))。

  • related: 相關(guān)資源鏈接。

  • data: 資源連接。

  • meta: 包含關(guān)于此關(guān)聯(lián)的非標(biāo)準(zhǔn)元信息的元對象。

更多介紹見 官方文檔。

· Yahoo elide 對 JSON API 的支持

點(diǎn)擊 http://elide.io/pages/guide/01-start.html,訪問 Yahoo elide 官方網(wǎng)站。

1. elide 介紹

elide 通過 Spring Data Jpa 的 Entity,加上自定義的 @Include(rootLevel = true) 注解,來完成 JSON API 標(biāo)準(zhǔn)的輸出。

使用方法如下圖所示:

效果如下:

生產(chǎn)環(huán)境中 HTTP 協(xié)議有哪些架構(gòu)

· RestTemplate 的重試和監(jiān)控

代碼如下。

@SpringBootApplication public class DubbingApiApplication {/** ? * 使用全局的 RestTemplate ? * 設(shè)置了連接超時時間、請求超時時間、異常重試次數(shù) 3 次 ? * 并且會記錄所有請求的詳細(xì)日志 ? * ? * @return ? */ ? @Bean ? public RestTemplate restTemplate() { ? ? ?RequestConfig config = RequestConfig.custom().setConnectionRequestTimeout(10000).setConnectTimeout(10000).setSocketTimeout(30000).build(); ? ? ?HttpClentBuilder builder = HttpClientBuilder.create().setDefaultRequestConfig(config).setRetryHandler(new DefaultHttpRequestRetryHandler(3, false)); ? ? ?HttpClient httpClient = builder.build(); ? ? ?ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); ? ? ?RestTemplate restTemplate = new RestTemplate(requestFactory); ? ? ?restTemplate.setInterceptors(Collections.singletonList(new LoggingRestTemplate())); ? ? ?restTemplate.setRequestFactory(new HttpComponentsAsyncClientHttpRequestFactory()); ? ? ?return restTemplate;}public static void main(String[] args) { ? ? ?SpringApplication.run(DubbingApiApplication.class, args);} }

· 請求格式和返回結(jié)果的格式約定。

(1)實(shí)現(xiàn) ResponseBodyAdvice 對 controller 返回的 Result 進(jìn)行統(tǒng)一的包裝,如下代碼。

public class ElideResponseBodyAdvice implements ResponseBodyAdvice{
? ? @Autowired
? ? private ElideProperties elideProperties;
? ? /**
? ? ?* 配置注解可以跳過去,類上,方法上都行
? ? ?*
? ? ?* @param returnType
? ? ?* @param converterType
? ? ?* @return
? ? ?*/
? ? ?@Override
? ? ?public boolean supports(MethodParameter returnType, Class converterType) {
? ? ? ? ?if (converterType != null && converterType.isAssignableFrom(StringHttpMessageConverter.class)) {
? ? ? ? ? ? ?return false;
? ? ? ? ?}
? ? ? ? ?ElideSkippable elideSkippable = returnType.getMethodAnnotation(ElideSkippable.class);
? ? ? ? ?if (elideSkippable == null) {
? ? ? ? ? ? ?elideSkippable = returnType.getDeclaringClass().getAnnotation(ElideSkippable.class);
? ? ? ? ?}
? ? ? ? ?return !(elideSkippable != null && elideSkippable.value());
? ? ?}
? ? ?@Override
? ? ?public Object beforeBodyWrite(
? ? ? Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
? ? ? ? ?HttpServletRequest httpServletRequest = ((
? ? ? ? ?ServletServerHttpRequest)
? ? ? ? ?request).getServletRequest();
? ? ? ? ?//only process elide persistable
? ? ? ? ?return
Result
ElideWrapHandler.process(httpServletRequest, body);

? ? ?} }

(2)異常統(tǒng)一格式的處理,返回固定的 error 級別的格式結(jié)果,如下代碼。

/*** 框架級別的通用異常處理*/ @ControllerAdvice @Slf4j @Order(4) public class ExceptionAdvice {@ExceptionHandler({BindException.class}) ? @ResponseBody ? public JsonApiErrorDocument exception(BindException e, HttpServletResponse response) { ? ? ?log.warn(e.getMessage(), e); ? ? ?ErrorResponse errors = new ErrorResponse(Constant.ERROR_VALIDATION, response.getStatus(), e.getMessage()); ? ? ?errors.setMeta(e.getAllErrors()); ? ? ?return new JsonApiErrorDocument(errors);} }

· 對緩存 Etag 的支持。

針對 HTTP 里 Etag 的支持,也需要我們框架層面去支持 Etag 緩存,這里就不給大家貼代碼了,大家可以思考一下。

微服務(wù)中 HTTP 與 RPC 的權(quán)衡

· HTTP 與 RPC 比較

實(shí)際工作中建議兩者都用,API 對外,Ali Dubbo 的 RPC 對內(nèi)部使用,這樣兩個的優(yōu)點(diǎn)都能使用到。

總結(jié):面試中起到的關(guān)鍵作用是什么?

如果面試中問到你這個問題,主要的考驗(yàn)的點(diǎn)有:

  • 思路是否清晰。

  • 實(shí)戰(zhàn)解決那些問題如緩存可能會讓你說的非常細(xì)。

  • 知識是否全面,及其是否針對一個問題了解的足夠多。

基本上面的東西如果你都能提到,面試官的印象基本上是非常好的,加分會加很多。

近期熱文

《這么糟糕的代碼,真的是我以前寫的嗎?》

《一條挨踢老狗的 2017 年終總結(jié)》

《OpenVPN 的穿墻遠(yuǎn)程連接旅程》

《前端跨域問題各種解決方案》

《程序員跳槽時,如何高效地準(zhǔn)備面試?》

「閱讀原文」看交流實(shí)錄,你想知道的都在這里

總結(jié)

以上是生活随笔為你收集整理的Java 架构师眼中的 HTTP 协议的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

一区二区三区免费网站 | 天天激情天天干 | 午夜精品一区二区三区在线观看 | 国产成人精品女人久久久 | 亚洲国产无 | 不卡的av在线播放 | 日日摸日日碰 | 天天躁日日躁狠狠躁 | 久久久久成人精品免费播放动漫 | 日韩欧美在线中文字幕 | 97超碰在线久草超碰在线观看 | 国产不卡在线看 | 欧美日韩69| www.com黄色 | www亚洲国产| 热re99久久精品国产66热 | 日韩在线观看三区 | 国产97色在线 | 国产一级片网站 | 999久久久免费精品国产 | 亚洲精品在线一区二区 | 天天摸天天舔 | 免费高清在线观看电视网站 | 久草观看 | 日本精品久久 | 国产精品黑丝在线观看 | 一本一本久久a久久 | 成人在线播放免费观看 | 天堂av高清 | 成人91在线观看 | 九九在线精品视频 | 9色在线视频 | 天天干天天怕 | 久草观看 | 欧美激情视频一二区 | 国产高清在线一区 | 国产欧美精品xxxx另类 | 亚洲91中文字幕无线码三区 | 在线观看黄网站 | 在线观看久 | 中文字幕在线播放视频 | 99综合电影在线视频 | 又色又爽又黄 | www.看片网站 | 少妇bbbb搡bbbb桶 | 午夜精品一区二区三区视频免费看 | 992tv在线成人免费观看 | 亚洲天堂网在线观看视频 | 精品视频区 | 涩涩网站在线看 | 国产精品一区在线 | 久青草电影 | 国产欧美日韩精品一区二区免费 | a级片久久久 | 日本爱爱免费 | 国产精品一区在线播放 | 麻豆成人网 | 欧美激情在线看 | 五月婷婷丁香在线观看 | 亚洲乱亚洲乱亚洲 | 中文字幕免费在线看 | 黄色一二级片 | 91日韩在线播放 | 伊人婷婷| 视频三区在线 | 欧美在线1 | 亚洲一二三久久 | 久久伊人婷婷 | 91亚洲精品在线观看 | 91在线播放国产 | 亚洲综合色站 | 91污在线 | 国产麻豆传媒 | 婷婷开心久久网 | 国产精品高清在线 | 亚洲男男gaygayxxxgv | 中文字幕有码在线 | 高清中文字幕av | 国产成人精品一二三区 | 97高清视频| 在线观看免费国产小视频 | 99一区二区三区 | 天天色天天干天天色 | 一区二区三区三区在线 | 一二三区av | 天堂av在线中文在线 | 国产精品免费观看国产网曝瓜 | 日日夜夜精品免费视频 | 国产在线精品一区二区三区 | 91一区二区三区在线观看 | www.色午夜.com| 国产精品美 | 国产最顶级的黄色片在线免费观看 | 亚洲精品自在在线观看 | 亚洲特级片 | 91成人在线观看高潮 | 一区二区三区日韩在线 | 中文字幕精品久久 | 日韩精品免费一区二区 | 伊人色综合久久天天 | 欧美91精品 | av青草 | 91精品视频在线观看免费 | 精品婷婷 | 久久免费视频2 | 99高清视频有精品视频 | 欧美xxxxx在线视频 | 国产精品日韩久久久久 | 精品久久久久久久久久国产 | 免费色av | 午夜精品久久久久久久久久久久久久 | 久久久久国产精品厨房 | 亚洲天堂色婷婷 | 中文字幕高清在线播放 | 色网站在线 | 日韩欧美电影在线 | 亚洲aaa级| av在线免费观看网站 | 国产成人三级在线 | 久视频在线 | 亚洲综合五月 | 亚洲一区二区三区四区精品 | 成年人在线免费视频观看 | 国产剧在线观看片 | 在线观看日韩中文字幕 | 国产一区二区在线免费 | 国产在线免费观看 | 欧美坐爱视频 | 片网址 | 国产精品女人网站 | 中文字幕在线观看不卡 | 精品自拍sae8—视频 | 免费精品在线视频 | 九九视频免费观看视频精品 | 91麻豆精品国产91久久久久久 | 99热精品国产 | 精品一区二区av | 一级久久精品 | 亚洲丝袜一区二区 | 免费看成人av | 精品久久久影院 | 91精品在线视频 | 国产 日韩 欧美 在线 | 精品久久久国产 | 国产精品久久久久久久午夜片 | 国产亚洲精品久久久久久大师 | 久久久久久国产精品久久 | 亚洲精品欧美视频 | 久久躁日日躁aaaaxxxx | 九九免费在线视频 | 中文字幕成人av | 在线观看www视频 | 亚洲激情电影在线 | 亚洲一区精品人人爽人人躁 | 免费色网站 | 欧美精品九九99久久 | 99久e精品热线免费 99国产精品久久久久久久久久 | 精品国产一区二区三区久久久蜜月 | 亚洲精品永久免费视频 | 日本久久综合网 | 久久这里有精品 | 亚洲作爱视频 | 911免费视频 | 久久久美女 | 97国产大学生情侣白嫩酒店 | 国精产品999国精产品岳 | 黄色av网站在线观看 | 在线观看av黄色 | 国产精品一二三 | 国产精品成人免费精品自在线观看 | 九九在线视频免费观看 | 亚州免费视频 | 日本黄网站 | 久久精品精品电影网 | 久久精品伊人 | 中文字幕在线高清 | 狠狠色丁香婷婷综合久小说久 | 超碰97久久 | 国产视频资源在线观看 | 国产日韩在线视频 | 午夜精品久久久久久久久久久久 | 粉嫩aⅴ一区二区三区 | 在线免费观看国产视频 | 中文字幕 婷婷 | 色99色 | 欧美一二三区播放 | 97超碰在线资源 | 免费黄色网址大全 | 99久久精品国产一区 | 九九免费在线观看视频 | av在线影片 | 奇人奇案qvod| 亚洲japanese制服美女 | av免费福利 | 午夜黄网 | 成人在线观看日韩 | 99爱这里只有精品 | 国产成人av福利 | 精品成人在线 | 超碰97在线人人 | 国产999视频在线观看 | 国产高清不卡一区二区三区 | 成人av高清在线观看 | 亚洲成年人在线播放 | 国产精品久久久久久久久久久久午 | 亚洲国产一二三 | 国产精品日韩高清 | 欧美一级电影 | 中文字幕av日韩 | 成年人国产在线观看 | 久久美女视频 | 2020天天干夜夜爽 | 国产一级特黄电影 | 国产中文伊人 | www.狠狠| 国产午夜精品一区二区三区嫩草 | 国产麻豆剧传媒免费观看 | 中文av网站 | 国产99久久精品一区二区永久免费 | 欧美日本中文字幕 | 国产成人在线综合 | 99性视频| 亚洲首页| 美腿丝袜一区二区三区 | 黄色软件在线观看 | 成人91在线 | 精品国产一区二区三区久久久 | 国产精品破处视频 | 久久久久久久久久久精 | 久久欧美在线电影 | 国产成人精品日本亚洲999 | 国产在线观看,日本 | 国产999视频 | www.久久精品视频 | 久久精品波多野结衣 | 国产不卡在线看 | 免费在线观看毛片网站 | 色99视频 | 欧美色图视频一区 | 91精品色 | 国产亚洲情侣一区二区无 | 国内精品久久久久久久久久清纯 | 日韩免费看 | 国产精品一区二区久久精品爱涩 | 00av视频| 99久久夜色精品国产亚洲96 | 四虎8848免费高清在线观看 | 久久久网站 | 日韩精品视频免费专区在线播放 | 中文字幕国内精品 | 麻豆视频免费播放 | 97超碰资源站| 国产视频日韩视频欧美视频 | 四虎成人免费影院 | 天天操天天操一操 | 亚洲专区在线 | 国精产品999国精产品岳 | 精品国产一区二区三区不卡 | 亚洲国内精品视频 | 午夜久久久久久久久久影院 | av专区在线 | 人人爽人人爱 | 精品久久综合 | 久久a级片| 婷婷激情综合五月天 | 日韩a在线播放 | 色香蕉在线视频 | 丁香电影小说免费视频观看 | 九九热免费在线观看 | 中文字幕视频一区二区 | 亚洲精品在线看 | 免费国产亚洲视频 | 九九九热视频 | 亚洲综合一区二区精品导航 | 国产精品一区二区在线观看 | 9999国产精品 | 久久久人人人 | 日韩精品一区二区三区外面 | www.成人sex| 天天操夜操视频 | 国产成人精品av在线观 | 欧美激情亚洲综合 | 国产黄免费 | 国产精品6 | 中文字幕在线成人 | 人人澡澡人人 | 久久艹艹 | 一级淫片a | 免费av福利 | 日韩精品中文字幕av | 黄色一级在线观看 | 久久怡红院 | 精品久久久久久久久久久院品网 | 国产精品午夜免费福利视频 | 波多野结衣在线观看一区 | 成年人在线 | 伊人午夜 | 欧洲精品视频一区二区 | 国产成人精品一区二区三区在线 | 国产在线观看你懂得 | 欧美另类xxxx | 久久精品国产一区二区电影 | 久久看视频 | 激情综合五月 | 久久久国产一区二区三区四区小说 | 成人毛片a | 在线黄色国产电影 | 欧美日韩国产亚洲乱码字幕 | 99 精品 在线| 国产精品网站一区二区三区 | 色久五月 | 久久99久久精品 | 91av资源网 | 国产精品视频内 | 中日韩在线| 国产拍揄自揄精品视频麻豆 | 国产一二三四在线观看视频 | 日韩av网页 | 蜜臀久久99精品久久久酒店新书 | 特级西西444www高清大视频 | 国产91精品一区二区麻豆网站 | 91网在线| 日韩欧美精品在线 | 人人要人人澡人人爽人人dvd | 久久国产精品久久久久 | 不卡av电影在线观看 | 亚洲春色成人 | 亚洲色图22p| 免费视频区| 97在线观看免费观看 | 91av在线视频播放 | 99视频在线免费 | 国产视频在线看 | 亚洲精品日韩一区二区电影 | 中文字幕4 | 在线电影日韩 | 99久久精品国产一区二区成人 | 亚洲视频在线观看 | 九九热在线播放 | 亚洲一级电影在线观看 | 天堂麻豆| 欧美一区三区四区 | 狠狠色丁香婷婷综合久小说久 | 亚洲精品视频免费观看 | 日本韩国欧美在线观看 | 一区二区三区电影在线播 | av永久网址 | 亚洲电影免费 | 99草视频在线观看 | 毛片网免费 | 久久综合之合合综合久久 | 又黄又刺激又爽的视频 | 中文高清av| 欧美精品久久久久 | 99看视频在线观看 | 日批视频在线 | 亚洲精品www| 久久免费国产视频 | 毛片精品免费在线观看 | 精品久久久久久久久久久院品网 | 激情五月***国产精品 | 午夜三级影院 | 特级西西444www高清大视频 | 日韩电影精品 | 天天干视频在线 | 夜夜躁日日躁狠狠久久88av | 中文字幕丝袜制服 | 夜夜高潮夜夜爽国产伦精品 | 911久久香蕉国产线看观看 | 国产在线精品一区二区不卡了 | 日韩午夜精品福利 | 久草网首页 | 免费又黄又爽视频 | 狠色狠色综合久久 | 久久99亚洲精品 | av观看免费在线 | 狠狠干婷婷色 | 国内精品美女在线观看 | 久久久久久美女 | 一区二区中文字幕在线 | 久久a v视频 | 免费a现在观看 | a在线视频v视频 | 玖玖玖国产精品 | 亚洲日本在线视频观看 | 亚洲自拍偷拍色图 | 免费福利视频网 | 亚洲精选在线 | 成人免费视频网站在线观看 | 成人小视频免费在线观看 | 久久人人97超碰精品888 | 日日夜夜精品网站 | 欧美日韩不卡一区二区 | 久久午夜精品视频 | 欧美日韩综合在线 | 日韩aⅴ视频 | 精品国产123 | 国产专区日韩专区 | 中文字幕av播放 | 久草电影在线观看 | 国产亚洲人 | 久久综合五月 | 成人av免费播放 | 久久免费视频7 | 欧美成人va | 欧美在线不卡一区 | 国产精品久久久久久电影 | 国产 日韩 欧美 中文 在线播放 | 日韩va欧美va亚洲va久久 | 久久久精品国产一区二区三区 | 婷婷中文字幕综合 | av一区在线播放 | 成人三级视频 | 亚洲国产日韩在线 | 在线免费视 | 天天舔天天搞 | 久久草网 | 久久精品一区二区三 | 狠狠色狠狠色合久久伊人 | 国产xvideos免费视频播放 | 日p视频 | 人人狠狠 | 又湿又紧又大又爽a视频国产 | 丁香婷婷综合色啪 | 日韩黄色av网站 | 在线观看亚洲精品视频 | 国产精品6 | 毛片激情永久免费 | 亚洲国产日本 | 国产精品淫片 | 久久久伦理 | 久久久久久久久久久电影 | 亚洲国产中文字幕在线观看 | 精品国模一区二区 | 91中文字幕视频 | 国产精品毛片网 | 超碰97在线资源 | 久久免费电影 | 一级精品视频在线观看宜春院 | 性色在线视频 | 国产成人一区二区三区 | 草久视频在线观看 | 2018亚洲男人天堂 | 中文字幕在线一区二区三区 | 丁香久久综合 | 午夜久久福利影院 | 国产精品不卡在线观看 | 丁香婷婷激情网 | 99久久精品费精品 | 精品国模一区二区 | 色停停五月天 | 粉嫩av一区二区三区四区在线观看 | 99九九热只有国产精品 | 欧美日韩免费一区 | 欧美一区影院 | 久久黄色免费观看 | 五月天激情视频在线观看 | 亚洲 欧洲av | 狠狠操91 | 日韩激情在线 | 91精品啪在线观看国产 | 国产精品区在线观看 | 久久99精品国产99久久6尤 | 国产精品高潮呻吟久久av无 | 亚洲日日夜夜 | 激情一区二区三区欧美 | 91精品视频免费在线观看 | 永久免费视频国产 | 美女网站免费福利视频 | 中文免费 | 99在线精品观看 | 欧美乱码精品一区二区 | 亚洲一区二区精品视频 | 亚洲区色 | 国产日韩在线视频 | 日韩.com| av黄色免费网站 | 欧美久久久久 | 国产99免费视频 | 精品不卡视频 | 亚洲天堂网在线观看视频 | 免费黄色网止 | 91精彩视频在线观看 | 免费欧美高清视频 | 国产精品原创视频 | 久热免费在线观看 | 一区二区三区在线观看 | 亚洲精品视频播放 | 久久精品视频网 | 久久只有精品 | 久久免费av电影 | 日韩天堂网 | 成人香蕉视频 | 91麻豆精品国产自产在线 | 一区二区精品国产 | 国产精品手机在线观看 | 国产一区二区高清不卡 | 国产原厂视频在线观看 | 97精品国产97久久久久久免费 | 91麻豆精品国产 | 日韩国产欧美视频 | 91视频免费播放 | 六月激情网| 在线视频 你懂得 | 可以免费看av| 欧美日韩精品综合 | 国产黄在线免费观看 | 久久人人爽人人 | 高清精品在线 | 国产高清在线精品 | 免费色网 | 婷婷伊人网 | 久久精品国产亚洲a | 色中色资源站 | 日韩电影黄色 | 欧美激情精品久久久久久 | 国产高清一区二区 | 特级西西444www大胆高清无视频 | 日韩免费成人 | 伊人亚洲精品 | 97精品久久人人爽人人爽 | 精品视频999 | 国产 日韩 在线 亚洲 字幕 中文 | 美女网站在线观看 | 精品主播网红福利资源观看 | 香蕉在线观看 | 韩国精品福利一区二区三区 | 中文字幕av日韩 | 在线v片| 99精品视频在线观看免费 | 国产九九九九九 | 人人爽人人舔 | 久久一区国产 | 少妇bbb搡bbbb搡bbbb | 久草精品视频 | 欧美va在线观看 | 91香蕉视频黄色 | 欧美美女视频在线观看 | 亚洲精品久久在线 | 人人射人人爱 | 国产精品白浆视频 | 中文字幕色综合网 | 国产一区二区三区免费在线 | 亚洲一级片免费观看 | 日韩色爱 | 亚洲精品美女免费 | 欧美成人黄色片 | 色婷婷导航 | 色婷婷国产精品 | 免费看国产a | 综合色天天 | 亚洲一二三久久 | 又大又硬又黄又爽视频在线观看 | 九九热视频在线播放 | 有码一区二区三区 | 中文字幕超清在线免费 | 欧美a级成人淫片免费看 | 天堂久色 | se婷婷 | 国产日韩精品一区二区三区 | 亚洲成av人影院 | 国产在线观看一 | 久草在线视频网 | 中文字幕av日韩 | av在线网站大全 | 精品国产电影一区 | 亚洲视频综合 | 亚洲国产高清在线观看视频 | www色网站| 我要看黄色一级片 | 久久久国产在线视频 | 欧美精品久久久久久久久久丰满 | 美女国产网站 | 国产精品久久久久久久久久久久久久 | 不卡的av电影在线观看 | 亚洲四虎影院 | 在线中文字幕视频 | 456免费视频| 日韩激情三级 | 六月丁香激情综合色啪小说 | 免费精品在线观看 | 999久久久欧美日韩黑人 | 精品色综合 | 日本黄色免费在线 | 99热精品在线 | 五月开心六月伊人色婷婷 | www.天天射.com| 丰满少妇一级片 | 国产精品麻豆欧美日韩ww | 免费观看av| 国产精品爽爽久久久久久蜜臀 | 久产久精国产品 | 精品一区二区免费在线观看 | 久草在线综合 | 亚洲免费在线视频 | 欧美一区中文字幕 | 国产精品久久久一区二区三区网站 | 成人国产精品免费观看 | 成人免费视频网址 | 在线中文字幕av观看 | 女人18片| 久久国产欧美日韩 | 精品一区二区av | 成年人毛片在线观看 | 免费观看久久久 | 韩国av一区二区三区在线观看 | 日韩视频免费在线观看 | 啪啪资源 | 在线视频观看你懂的 | 精品久久久久一区二区国产 | 国内精品一区二区 | 91成人网在线 | 天堂av免费 | 五月天欧美精品 | 午夜精品视频一区二区三区在线看 | 在线免费观看黄色av | 99视频精品免费视频 | 精品在线二区 | 黄网在线免费观看 | 五月婷婷激情 | 欧美三级在线播放 | 1区2区3区在线观看 三级动图 | 亚洲综合五月天 | 91免费国产在线观看 | 亚洲成人精品在线观看 | 日本黄区免费视频观看 | 国产一区二区精品久久91 | 亚洲在线精品视频 | 一区中文字幕在线观看 | 国产第一页福利影院 | 波多野结衣网址 | av观看网站 | 五月天中文在线 | 亚洲黄色网络 | 很黄很色很污的网站 | 一色屋精品视频在线观看 | 中文字幕一区二区三区四区 | 97超在线| 91热| 一区二区三区免费在线播放 | 狠狠干夜夜爽 | 在线观看免费日韩 | 成年人免费电影在线观看 | 可以免费观看的av片 | 在线黄色毛片 | 亚洲最新合集 | 丰满少妇在线观看 | www久久精品 | 国产九九九精品视频 | 99精品黄色片免费大全 | 中文字幕999 | 欧美极品少妇xbxb性爽爽视频 | 91高清在线看| 色综合咪咪久久网 | 国产明星视频三级a三级点| 国产精品日韩在线观看 | 久久成人综合 | 国产系列在线观看 | 国产中文在线视频 | 人人看人人 | 9在线观看免费高清完整版在线观看明 | 久久黄色网页 | 天天干夜夜夜 | 韩国av免费在线 | 天天射天天干天天爽 | 国产1区2 | 91在线看免费 | 午夜少妇av | 成人久久久久久久久久 | freejavvideo日本免费 | 国产精品综合久久久久 | 国产精品嫩草55av | 欧美黄色特级片 | 欧美激情精品久久 | 日韩欧美一二三 | 久久久久久久久久久久电影 | www视频免费在线观看 | 97视频人人免费看 | 91精品国产一区二区三区 | 欧美成人在线免费观看 | 欧美激情综合五月 | 草久在线观看 | 婷婷电影在线观看 | 三级av免费 | 日韩综合一区二区 | 91中文字幕| 五月婷婷丁香激情 | av电影在线观看完整版一区二区 | 国产色秀视频 | 久草视频在线免费播放 | 91在线公开视频 | 日韩美在线观看 | 欧美激情奇米色 | 亚洲一区二区精品视频 | 日韩三级久久 | 丰满少妇一级 | 97超碰在线人人 | 日韩有码网站 | 正在播放日韩 | 免费91麻豆精品国产自产在线观看 | 欧美一级日韩三级 | 国产黄色片免费观看 | 99国产在线 | 精品伦理一区二区三区 | 国产精品男女啪啪 | 美女久久久久久久久久久 | 国产v在线 | 久久久久精| 国产区高清在线 | 免费a一级 | av电影在线免费观看 | 91精品国产成人观看 | 日韩一级片大全 | av在线免费观看黄 | 精品国产观看 | 国产又粗又猛又黄又爽的视频 | 亚洲精品乱码久久久久久蜜桃不爽 | 天堂av官网 | 免费看久久久 | 免费a视频| 在线视频一区观看 | 久草精品在线播放 | 最近中文字幕在线播放 | 国产亚洲无 | 2018亚洲男人天堂 | 外国av网| 黄色网在线免费观看 | 91福利试看| 亚洲欧美综合 | 99久久成人 | 日韩在线免费不卡 | 日韩av高清在线观看 | 97av影院| 日韩高清片 | 亚洲色图av | 麻豆免费视频 | 久久久久久久久久亚洲精品 | 免费在线播放av电影 | 久久久久黄 | 久久亚洲精品电影 | 五月婷婷六月综合 | 97综合在线| 国产视频91在线 | 国产视频日韩视频欧美视频 | 91探花国产综合在线精品 | 91精品久久久久久综合乱菊 | 久久精彩免费视频 | 91免费看片黄 | 国产香蕉97碰碰碰视频在线观看 | 亚洲一片黄 | 色99之美女主播在线视频 | 午夜美女视频 | 五月天婷婷免费视频 | 中文字幕视频在线播放 | 久久久国产高清 | 日韩午夜av电影 | 亚洲精品美女在线观看播放 | 日韩精品大片 | 久久成人人人人精品欧 | 午夜精品在线看 | 日本性久久 | 成人影音av| 在线观看911视频 | 成人精品电影 | 91麻豆精品91久久久久同性 | 蜜臀av夜夜澡人人爽人人 | 天天操夜夜摸 | 精品一区精品二区高清 | 狠狠综合| 成人久久久电影 | av福利第一导航 | 午夜久久美女 | 99精品国自产在线 | 天天操天天干天天爽 | 国产黄色在线看 | av国产在线观看 | 黄色免费网战 | 在线不卡中文字幕播放 | 久久在线 | 国产精品一二 | 日本午夜在线观看 | 一本之道乱码区 | 天天射色综合 | 亚洲精品久久久久久中文传媒 | 91亚瑟视频| 欧美亚洲另类在线视频 | 欧美精品免费一区二区 | 久久久精品午夜 | 国产中文在线视频 | 精品久久久亚洲 | 久久这里只有精品久久 | 91av网站在线观看 | 99久久综合国产精品二区 | 在线 日韩 av | 91精品成人 | 日韩精品一区二区免费视频 | 欧美一区二区伦理片 | 亚洲精色 | 日韩在线观| 国产精品24小时在线观看 | 国产在线一区二区三区播放 | 激情网婷婷 | 91久久精品日日躁夜夜躁国产 | 欧美一区二区三区在线 | 亚洲精品日韩av | 五月婷婷播播 | 国产精品99久久久精品免费观看 | 人人插超碰 | 最近中文字幕免费大全 | 尤物97国产精品久久精品国产 | 久久99国产综合精品 | 久久免费99精品久久久久久 | 婷婷六月网 | 四虎5151久久欧美毛片 | 狠狠色丁香久久综合网 | 国产一区欧美一区 | 日韩网站在线观看 | aaa日本高清在线播放免费观看 | 免费网址在线播放 | 五月天色站 | 日韩视频在线不卡 | 日日夜夜精品视频天天综合网 | 亚洲一区二区三区四区在线视频 | 91探花系列在线播放 | 一区二区三区免费在线观看视频 | 国产成人综 | 日韩欧美在线国产 | 国产视频一区二区在线观看 | 久久久久女人精品毛片 | 成人av网站在线播放 | 日韩精品视频在线观看网址 | 久草在线官网 | 97精品超碰一区二区三区 | 国产精品欧美一区二区三区不卡 | 91在线视频观看 | 久久精品xxx | 91成人久久| 全黄网站 | 欧美日韩视频在线一区 | 天天色天天爱天天射综合 | 黄色午夜网站 | 色网站黄| 日韩3区| 久草在线免费看视频 | 一级片视频在线 | 天天曰 | 少妇bbw揉bbb欧美 | 碰天天操天天 | 婷婷色九月 | 国产精品乱码一区二三区 | 婷婷国产一区二区三区 | 婷婷网五月天 | 玖玖国产精品视频 | 激情五月激情综合网 | 亚洲综合婷婷 | 最新av免费| 国产玖玖精品视频 | 日韩免费播放 | 999成人免费视频 | 97视频免费观看 | 亚洲 欧美变态 另类 综合 | 久久网站av | 特级西西444www大精品视频免费看 | 中文字幕在线观看第一页 | 伊人久久av | 国产精品乱码久久久久久1区2区 | 超碰在线观看97 | 99热精品在线观看 | 欧美另类网站 | 公开超碰在线 | 日本三级中文字幕在线观看 | 色99色| 国产精品美女久久久久久久 | 国产麻豆果冻传媒在线观看 | 国产麻豆精品一区 | 国产玖玖精品视频 | 麻豆你懂的 | 精品国产1区二区 | 国产剧情av在线播放 | 久久久久久久久久久综合 | 久久涩视频 | 国产成人61精品免费看片 | 九色精品免费永久在线 | 96av在线视频| 91香蕉嫩草 | av永久网址 | 久久久国产一区二区三区 | 99欧美 | 99精品欧美一区二区三区 | 在线观看岛国片 | 亚洲成人av片在线观看 | 精品在线一区二区 | 一级片视频免费观看 | 久久精品官网 | 久久久99精品免费观看app | 国产中文伊人 | 黄色国产在线 | 国产在线播放一区 | 国产一区视频导航 | 人人爽人人乐 | 国产亚洲一级高清 | 91丨九色丨91啦蝌蚪老版 | 中文在线字幕观看电影 | 在线国产一区 | 一区二区三区四区五区在线 | 欧美与欧洲交xxxx免费观看 | 亚洲精品乱码久久久久久写真 | 国产中文字幕视频 | 久久婷婷综合激情 | 成人网444ppp | 激情久久综合网 | 久99久在线视频 | 国产精品久久久久久久电影 | 国产精品 中文在线 | 欧美性精品 | 国产一区二区高清 | 日日激情| 亚洲天堂va | 亚洲精品视频在线免费播放 | 国产精成人品免费观看 | 4p变态网欧美系列 | 日韩视频三区 | 激情影音先锋 | 成年人在线看片 | 亚洲精品成人av在线 | 2017狠狠干 | 91九色蝌蚪视频网站 | 超碰在线个人 | 午夜精品视频免费在线观看 | 丁香电影小说免费视频观看 | 日日摸日日碰 | 久久精品福利视频 | 免费看片网址 | 91免费高清在线观看 | 国产视频在线观看一区 | 亚洲欧美国产视频 | 日韩欧美专区 | 久久高清国产视频 | 99精品国自产在线 | 国产色爽 | 亚洲视频2 | 超碰夜夜 | 国内精品美女在线观看 | 色福利网 | 999成人| 中文字幕一区二区三区久久 | 青草视频在线看 | 亚洲三级在线免费观看 | 不卡电影一区二区三区 | 99免费精品视频 | 午夜精品视频一区二区三区在线看 | 丁香婷婷网 | 亚洲一区二区三区精品在线观看 | 精品久久五月天 | 天天综合人人 | 色久天| 摸bbb搡bbb搡bbbb | 黄色中文字幕在线 | 国产1区2区3区在线 亚洲自拍偷拍色图 | 91热爆在线观看 | 69xx视频 | 国产流白浆高潮在线观看 | 久久久免费观看完整版 | 久久综合精品国产一区二区三区 | 日本精品一区二区 | 欧美色图视频一区 | 欧美a级成人淫片免费看 | 中文资源在线观看 | 国产精品高清免费在线观看 | 在线欧美中文字幕 | 欧美在线a视频 | av免费看网站 | 国产精品黄色 | 天天天天射 | 亚洲精品自在在线观看 | 国产区网址 | 粉嫩一区二区三区粉嫩91 | 成人在线视频观看 | 日韩在线短视频 | 久久尤物电影视频在线观看 | 国产成在线观看免费视频 | 97视频一区 | 日韩免费电影一区二区 | 中文字幕人成一区 | 久精品视频免费观看2 | 91亚洲精品国偷拍自产在线观看 | 久久夜av | 又黄又爽又色无遮挡免费 | 三级视频日韩 | 色美女在线 | 狠狠操操操 | 成人动漫一区二区三区 | 97超碰福利久久精品 | 国产一区视频在线 | 蜜臀一区二区三区精品免费视频 | 久久不卡电影 | 亚洲闷骚少妇在线观看网站 | 成人一区不卡 |