Netty源碼解析之 java網(wǎng)絡(luò)編程篇(3)


目錄

  1. http協(xié)議是個什么東西
  2. http的請求類型都有哪些
  3. 常見的HTTP首部
  4. HTTP請求體
  5. HTTP響應(yīng)體
  6. HTTP常見的響應(yīng)狀態(tài)碼
  7. HTTP的cookieg管理

HTTP協(xié)議

HTTP是一種通用的網(wǎng)絡(luò)數(shù)據(jù)傳輸格式优炬,它的傳輸內(nèi)容不僅僅局限于HTML文件或者圖片,所有可以用字節(jié)序列表示的數(shù)據(jù)都可以使用HTTP進行傳輸。

HTTP通過TCP/IP進行數(shù)據(jù)傳輸味混,如果忽略底層的TCP協(xié)議的握手和揮手的細節(jié),對于從客戶端到服務(wù)器的每一個請求和請求的響應(yīng)姊舵,在HTTP1.0有下面幾個步驟:

  1. 默認情況下亩鬼,客戶端在端口80開啟與服務(wù)器的一個TCP連接,當然也可以指定其他的端口村生。
  2. 客戶端向服務(wù)器發(fā)送消息嘉涌,請求指定路徑上的資源妻熊。一個HTTP請求包括一個首部,可選項包括一個空行和這次請求的數(shù)據(jù)仑最。
  3. 服務(wù)器向客戶端發(fā)送響應(yīng)扔役。響應(yīng)以響應(yīng)碼開頭,接著是包含元數(shù)據(jù)的首部警医,可選項包括一個空行以及所請求的文檔數(shù)據(jù)或者錯誤信息亿胸。
  4. 服務(wù)器關(guān)閉TPC連接坯钦。

在HTTP1.1(目前最常用的就是HTTP1.1)以及以后的HTTP版本中,可以通過一個TCP連接連續(xù)發(fā)送多個請求和接收多個響應(yīng)侈玄。

也就是說婉刀,上面的1和4步驟中間的2和3步驟可以反復執(zhí)行多次。另外拗馒,HTTP1.1中路星,請求數(shù)據(jù)和響應(yīng)數(shù)據(jù)可以分塊發(fā)送溯街,提高了擴展性诱桂。

HTTP請求方法

HTTP請求方法 描述 是否安全 是否冪等
GET 通常用于請求服務(wù)器獲取某個資源
HEAD 類似于GET,但是響應(yīng)結(jié)果中不包含響應(yīng)體呈昔,只包含協(xié)議信息和首部挥等,通常用于測試資源是否存在或者是否被修改 -
POST 客戶端向服務(wù)器提交數(shù)據(jù)(支持HTML的表單數(shù)據(jù)),可能會導致新的資源的建立或者已有資源的修改
PUT 從客戶端向服務(wù)器傳送的數(shù)據(jù)取代指定的文檔的內(nèi)容(全部取代)
PATCH 客戶端向服務(wù)器傳送的數(shù)據(jù)取代指定的文檔的內(nèi)容(部分取代)
TRACE 回顯客戶端請求服務(wù)器的原始請求報文堤尾,用于"回環(huán)"診斷 -
OPTIONS 請求服務(wù)器獲取服務(wù)器支持的各種功能肝劲,可以詢問服務(wù)器支持什么類型的HTTP方法,一般用于性能測試 -
DELETE 請求服務(wù)器刪除指定的資源

安全 : 意味著使用該種HTTP請求方法不會發(fā)生任何數(shù)據(jù)的修改或者更新動作郭宝,也就是請求多次也不會影響到資源的狀態(tài)辞槐。

冪等 : 意味著使用該HTTP請求方法請求多次HTTP調(diào)用,無論調(diào)用多少次粘室,請求結(jié)果或者資源的狀態(tài)是一樣的榄檬。

HTTP方法的安全性和冪等性是我們在設(shè)計HTTP接口時候需要重點考慮的兩個因素。

上面提到的POST和PUT方法的功能可以理解為相同的衔统,兩者的主要區(qū)別在于POST不是冪等的鹿榜,而PUT是冪等的。

在目前的Web開發(fā)中锦爵,POST方法已經(jīng)被濫用舱殿,一般很少人會使用PUT,除非是推崇RESTFUL風格編程险掀。

PUT方法和PATCH方法的功能類似沪袭,都是用客戶端請求的數(shù)據(jù)去替換掉服務(wù)器中指定文檔中的內(nèi)容,不過PUT方法是全部替換樟氢,而PATCH方法是部分替換枝恋。

常見的HTTP首部

字段 首部類型 描述
User-Agent 請求 用戶代理,用于告知服務(wù)器當前客戶端使用的是什么瀏覽器
Host 請求 用于指定接收該請求的服務(wù)器的主機名和端口號
Accept-Charset 請求 告知服務(wù)器客戶端可以接收和處理哪些字符集
Accept-Encoding 請求 告知服務(wù)器客戶端可以接收和處理哪些編碼方式
Accept-Language 請求 告知服務(wù)器客戶端可以接收和處理哪些語言
Accept 請求 告知服務(wù)器客戶端可以接收和處理哪些媒體類型
Referer 請求 提供了包含當前請求的URL的文檔的URL
Cookie 請求 客戶端通過它向服務(wù)器傳送一個或者多個令牌嗡害,原則上Cookie并不是安全的首部呢诬,Cookie的內(nèi)容也會緩存在客戶端。
Cache-Control 請求 告知服務(wù)器對當前的請求的響應(yīng)結(jié)果進行緩存相關(guān)操作
Content-Type 通用 告知服務(wù)器或者客戶端當前請求或者響應(yīng)結(jié)果的內(nèi)容(媒體)類型
Content-Length 通用 告知服務(wù)器或者客戶端當前請求或者響應(yīng)數(shù)據(jù)體的長度
Connection 請求 否需要持久連接集绰,如果指定為Keep-Alive揭保,可以提供持久連接
Origin 請求 指明當前的請求是一個針對跨域資源共享的請求
Access-Control-Allow-Origin 響應(yīng) 表示服務(wù)器允許的該跨域資源共享的請求來源
Server 響應(yīng) 用于告知客戶端服務(wù)器的相關(guān)信息
Set-Cookie 響應(yīng) Cookie對應(yīng),表示服務(wù)器設(shè)置成功的Cookie
Content-Encoding 響應(yīng) Accept-Encoding對應(yīng),用于服務(wù)器告知客戶端當前響應(yīng)結(jié)果的內(nèi)容編碼
Content-Language 響應(yīng) 與Accept-Language對應(yīng)鹃骂,用于服務(wù)器告知客戶端當前響應(yīng)結(jié)果的內(nèi)容語言

其中 Accept的值可以是以下八種頂級的類型

text/* 表示人可讀的文字台盯。
image/* 表示圖片。
model/* 表示3D模型畏线,如VRML文件静盅。
audio/* 表示音頻。
video/* 表示多媒體圖片寝殴、視頻蒿叠,也可能是音頻。
application/* 表示二進制數(shù)據(jù)蚣常。
message/* 表示協(xié)議特定的信封市咽,如Email消息和HTTP響應(yīng)。
muitipart/* 表示多個文檔和資源的容器抵蚊。

HTTP請求體

如果采用GET請求方法施绎,只需要向遠處服務(wù)器提供URL,URL中的路徑和查詢字符串就可以匹配到需要查詢的資源贞绳。

但是URL中無法提供詳細的客戶端信息谷醉,像POST和PUT這些請求方法所攜帶的數(shù)據(jù)體有可能比較大。

因此HTTP需要請求體冈闭。HTTP請求體包括下面四個部分:

  • 一個起始請求行俱尼,包括HTTP方法、路徑拒秘、查詢字符串以及HTTP版本号显。
  • HTTP請求的首部。
  • 一個空行(兩個連續(xù)的回車或者換行對)躺酒。
  • 請求數(shù)據(jù)體押蚤。
GET /wp-admin/admin-ajax.php?postviews_id=23996&action=postviews&_=1538708851063 HTTP/1.1
Host: www.importnew.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36
Referer: http://www.importnew.com/23996.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9

postviews_id=23996&action=postviews&_=1538708851063

HTTP響應(yīng)體

響應(yīng)體和請求體的格式類似,主要是返回服務(wù)器的響應(yīng)數(shù)據(jù)到客戶端羹应,包括服務(wù)器的一些信息和響應(yīng)數(shù)據(jù)體揽碘。HTTP響應(yīng)體主要包括下面的四個部分:

1、一個起始響應(yīng)行园匹,包括HTTP版本雳刺、狀態(tài)碼、狀態(tài)碼描述裸违。

2掖桦、HTTP響應(yīng)的首部。

3供汛、一個空行(兩個連續(xù)的回車或者換行對)枪汪。

4涌穆、響應(yīng)數(shù)據(jù)體。

HTTP/1.1 200 OK
Server: nginx
Date: Fri, 05 Oct 2018 03:07:37 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Keep-Alive: timeout=2
Vary: Accept-Encoding
X-Powered-By: PHP/5.3.3
X-Robots-Tag: noindex
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Content-Encoding: gzip

2995

Keep-Alive

在使用HTTP1.0的時候會為每個請求打開一個新的TCP連接雀久,實際上宿稀,這導致了一個典型Web會話中打開和關(guān)閉所有連接所花費的事件遠遠大于實際傳輸數(shù)據(jù)所消耗的時間,特別是響應(yīng)結(jié)果包含很多小文檔的會話赖捌。對于使用SSL或者TLS加密的HTTPS連接祝沸,這個問題更加嚴重,因為建立一個安全的Socket的握手過程遠比建立常規(guī)的Socket需要更多的工作越庇。

在HTTP1.1和后面的版本中罩锐,服務(wù)器不必在返送響應(yīng)之后就關(guān)閉連接。已經(jīng)建立的連接可以保持打開悦荒,在同一個Socket上等待來自客戶端的新請求唯欣。簡單來說嘹吨,就是可以在一個TCP連接上連續(xù)發(fā)送多個請求和連續(xù)進行多個請求的響應(yīng)搬味。

客戶端可以在HTTP請求首部中添加一個Connection請求頭,指定值為Keep-Alive蟀拷,這樣就能實現(xiàn)Socket的重用:

Connection: Keep-Alive
HTTP1.1或者之后的版本碰纬,Keep-Alive是默認開啟的,不需要顯式指定问芬,如果需要關(guān)閉可以設(shè)置為close:

Connection: close
一旦開啟了Keep-Alive悦析,服務(wù)器在關(guān)閉一個Socket連接之前,如果有新的客戶端再次連接到服務(wù)器此衅,那么就是重用Socket强戴。在JDK中可以通過系統(tǒng)屬性來控制如果使用HTTP的Keep-Alive:

http.keepAlive:默認值為true,默認開啟HTTP的Keep-Alive挡鞍。

http.maxConnections:同時保持打開的Socket數(shù)量的最大值骑歹,默認值為5。

http.keepAlive.remainingData:默認值為false墨微,如果設(shè)置為true道媚,則JDK在丟棄連接之后會完成剩余數(shù)據(jù)的清理。

sun.net.http.errorstream.enableBuffering:默認值為false翘县,如果設(shè)置為true最域,則嘗試緩存400和500狀態(tài)碼的相對小的錯誤流,從而能釋放連接以備后續(xù)使用锈麸。

sun.net.http.errorstream.bufferSize:為緩存錯誤流的緩沖區(qū)的字節(jié)大小镀脂,默認值為4096字節(jié),只有上一項為true的時候才有意義忘伞。

sun.net.http.errorstream.timeout:默認值為300ms薄翅,讀取錯誤流超時的毫秒數(shù)钞馁。

常見的HTTP狀態(tài)碼

簡單的說

  • 響應(yīng)碼100-199表示一個提供信息的響應(yīng)。
  • 響應(yīng)碼200-299表示請求成功匿刮。
  • 響應(yīng)碼300-399表示重定向僧凰。
  • 響應(yīng)碼400-499表示一個客戶端引發(fā)的錯誤。
  • 響應(yīng)碼500-599表示一個服務(wù)器引發(fā)的錯誤熟丸。
狀態(tài)碼 狀態(tài)碼消息 含義 HttpURLConnection中的常量 簡單描述
1xx - 信息狀態(tài)碼训措。 - 不常見,暫不考慮
100 Continue 服務(wù)器準備接受請求主體光羞,客戶端發(fā)送請求主體绩鸣;這允許客戶端在請求發(fā)送大量數(shù)據(jù)之前詢問服務(wù)器是否接受請求。 - 不常見纱兑,暫不考慮
101 Switching Protocols 服務(wù)器接受客戶端在Upgrade首部字段中要求改變應(yīng)用的協(xié)議請求呀闻,如從HTTP轉(zhuǎn)換為WebSockets。 - 不常見潜慎,暫不考慮
2xx - 表示請求成功捡多。 - -
200 OK 最常見的響應(yīng)碼,代表請求成功铐炫。如果請求方法是GET或者POST垒手,所請求的數(shù)據(jù)與正常的首部都包含在響應(yīng)體中。如果請求方法是HEAD倒信,則只包含首部信息科贬。 HTTP_OK 處理請求成功
201 Created 服務(wù)器已經(jīng)在響應(yīng)體中指定的URL創(chuàng)建了對應(yīng)的資源”钣疲客戶端現(xiàn)在應(yīng)當嘗試加載該URL榜掌。這個響應(yīng)碼只在響應(yīng)POST請求時發(fā)送。 HTTP_CREATED 創(chuàng)建成功
202 Accepted 表示請求已經(jīng)被處理乘综,但是處理尚未結(jié)束憎账,所以不會返回任何響應(yīng)數(shù)據(jù)。 HTTP_ACCEPTED 接受請求
203 Non-Authoritative Information 由緩存代理或者其他本地源返回資源的表示瘾带,不能保證是最新的鼠哥。 HTTP_NOT_AUTHORITATIVE 無權(quán)威的返回結(jié)果
204 No Content 服務(wù)器已經(jīng)成功處理了該請求,但是沒有信息發(fā)回給客戶端看政。一般是由于服務(wù)器上的表單處理邏輯的問題朴恳,只接收數(shù)據(jù)不返回數(shù)據(jù)。 HTTP_NO_CONTENT 無返回內(nèi)容
205 Reset Content 服務(wù)器已經(jīng)成功處理了該請求允蚣,但是沒有信息發(fā)回給客戶端于颖。客戶端應(yīng)該清除發(fā)送請求的表單信息嚷兔。 HTTP_RESET 重置內(nèi)容
206 Partial Content 服務(wù)器返回客戶端請求的資源的部分內(nèi)容森渐,而不是整個文檔做入。 HTTP_PARTIAL 部分內(nèi)容
3xx - 重定向。 - -
300 Multiple Choices 服務(wù)器為所請求的文檔提供一組不同的表示同衣。 HTTP_MULT_CHOICE 多重選擇
301 Moved Permanently 資源已經(jīng)移動到一個新的URL竟块。客戶端應(yīng)當自動加載這個URL的資源耐齐。 HTTP_MOVE_PERM 永久移動
302 Moved Temporarity 資源暫時移動到一個新的URL浪秘,但其位置在不久的將來還會再次改變。 HTTP_MOVE_TEMP 臨時移動
4xx - 客戶端錯誤 - -
400 Bad Request 客戶端向服務(wù)器發(fā)出的請求使用了不正確的語法埠况。 HTTP_BAD_REQUEST 錯誤請求
401 Unauthorized 訪問這個URL需要身份驗證耸携,一般是用戶名和口令。 HTTP_UNAUTHORIZED 未授權(quán)
403 Forbidden 服務(wù)器理解請求辕翰,但是有意拒絕進行處理夺衍。 HTTP_FORBIDDEN 禁止訪問
404 Not Found 最常見的錯誤響應(yīng),指示服務(wù)器找不到所請求的資源喜命。 HTTP_NOT_FOUND 未找到資源
405 Method Not Allowed 請求方法不支持用于請求指定的資源沟沙。 HTTP_BAD_METHOD 方法禁用
406 Not Acceptable 所請求的資源不能以客戶端希望的格式提供,客戶端期望的格式由請求HTTP首部Accept字段指定渊抄。 HTTP_NOT_ACCEPTABLE 不接受
5xx - 服務(wù)端錯誤 - -
500 Internale Server Error 服務(wù)器內(nèi)部異常尝胆。 HTTP_SERVER_ERROR 服務(wù)器異常
501 Not Implemented 服務(wù)器不具備完成請求的功能丧裁。 HTTP_NOT_IMPLEMENTED 尚未實現(xiàn)
502 Bad Gateway 服務(wù)器作為網(wǎng)關(guān)或代理护桦,從上游服務(wù)器收到無效響應(yīng)。 HTTP_BAD_GATEWAY 錯誤網(wǎng)關(guān)
503 Service Unavailable 服務(wù)器暫時無法處理請求煎娇,可能是超負荷或者維護等原因二庵。 HTTP_UNAVAILABLE 服務(wù)不可用

Cookie和Cookie管理

一般在Servlet應(yīng)用中,Cookie是識別當前用戶缓呛,實現(xiàn)持久會話的最佳方式催享。

從過期時間分類來看,Cookie分為會話Cookie和持久Cookie哟绊,會話Cookie的過期時間比較短因妙,持久Cookie的過期時間比較長或者不會過期,Cookie的過期策略等控制應(yīng)該由服務(wù)端控制票髓。

由于Cookie是直接暴露在客戶端攀涵,一般不能使用Cookie存放敏感的數(shù)據(jù),需要存放敏感數(shù)據(jù)可以考慮使用數(shù)據(jù)加密處理洽沟。

很多網(wǎng)站使用一些小文本串在連接之間存儲持久的客戶端狀態(tài)以故,這些小文本串稱為Cookie(中文翻譯為:小甜點)。

Cookie在請求和響應(yīng)的首部從服務(wù)器傳到客戶端裆操,再從客戶端傳回服務(wù)器怒详,服務(wù)器使用Cookie來指示sessionID炉媒、購物車內(nèi)容、登錄憑據(jù)等昆烁。

除了簡單的name=value對吊骤,Cookie可以有多個屬性來控制它們的作用域,包括過期日期、路徑静尼、域水援、端口、版本和安全選項茅郎。

JDK中java.net.CookieStore類提供了對Cookie的增刪查操作蜗元,它的默認實現(xiàn)是java.net.InMemoryCookieStore,如果實現(xiàn)CookieStore系冗,JDK中的Cookie默認是存放在內(nèi)存中的奕扣。

另外,java.net.CookieManager內(nèi)部持有CookiePolicy和CookieStore掌敬,定義了一系列管理Cookie的方法惯豆,一般通過CookieManager操作Cookie,當然也可以通過實現(xiàn)CookieStore奔害,覆蓋默認的CookieManager來實現(xiàn)Cookie的自定義管理楷兽。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市华临,隨后出現(xiàn)的幾起案子芯杀,更是在濱河造成了極大的恐慌,老刑警劉巖雅潭,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件揭厚,死亡現(xiàn)場離奇詭異,居然都是意外死亡扶供,警方通過查閱死者的電腦和手機筛圆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來椿浓,“玉大人太援,你說我怎么就攤上這事“獍” “怎么了提岔?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長左腔。 經(jīng)常有香客問我唧垦,道長,這世上最難降的妖魔是什么液样? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任振亮,我火速辦了婚禮巧还,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘坊秸。我一直安慰自己麸祷,他們只是感情好,可當我...
    茶點故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布褒搔。 她就那樣靜靜地躺著阶牍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪星瘾。 梳的紋絲不亂的頭發(fā)上走孽,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天,我揣著相機與錄音琳状,去河邊找鬼磕瓷。 笑死,一個胖子當著我的面吹牛念逞,可吹牛的內(nèi)容都是我干的困食。 我是一名探鬼主播,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼翎承,長吁一口氣:“原來是場噩夢啊……” “哼硕盹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起叨咖,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤瘩例,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后芒澜,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體仰剿,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年痴晦,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片琳彩。...
    茶點故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡誊酌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出露乏,到底是詐尸還是另有隱情碧浊,我是刑警寧澤,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布瘟仿,位于F島的核電站箱锐,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏劳较。R本人自食惡果不足惜驹止,卻給世界環(huán)境...
    茶點故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一浩聋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧臊恋,春花似錦衣洁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至撤卢,卻和暖如春环凿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背放吩。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工拷邢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人屎慢。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓瞭稼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親腻惠。 傳聞我的和親對象是個殘疾皇子环肘,可洞房花燭夜當晚...
    茶點故事閱讀 43,562評論 2 349

推薦閱讀更多精彩內(nèi)容