相信HTTP協(xié)議大家都不陌生,無(wú)論是網(wǎng)頁(yè)瀏覽,還是REST或WebService等常見消息交互,都是基于HTTP的。
HTTP協(xié)議位于網(wǎng)絡(luò)分層模型中的應(yīng)用層,基于TCP/IP通信協(xié)議來(lái)傳遞數(shù)據(jù),傳遞的數(shù)據(jù)由起始行、消息頭、空行和消息體組成。其中,起始行在客戶端請(qǐng)求時(shí)為請(qǐng)求行,在服務(wù)端響應(yīng)時(shí)為狀態(tài)行。
例如,服務(wù)端響應(yīng)消息長(zhǎng)這樣:

我們可以看到,HTTP頭由多個(gè)頭域組成,每個(gè)頭域由一個(gè)域名,冒號(hào)(:)和域值三部分組成,域名是大小寫無(wú)關(guān)。
HTTP起始行和消息頭中包含了訪問(wèn)URL、狀態(tài)碼、來(lái)源IP主機(jī)、報(bào)文大小等信息,這些信息對(duì)日常開發(fā)調(diào)試或運(yùn)維排錯(cuò)有極大幫助,因此對(duì)HTTP消息中的部分常見信息做個(gè)介紹供大家了解和使用。
獲取HTTP頭信息
通過(guò)瀏覽器的開發(fā)者工具可以很方便的看到頭信息。

若想通過(guò)Java編碼來(lái)獲取,可基于HttpServletRequest對(duì)象來(lái)做到,例如將頭域的鍵值對(duì)存儲(chǔ)在Map中:
import javax.servlet.http.HttpServletRequest;
private HttpServletRequest request;
//get request headers
private Map<String, String> getHeadersInfo() {
Map<String, String> map = new HashMap<String, String>();
Enumeration headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String key = (String) headerNames.nextElement();
String value = request.getHeader(key);
map.put(key, value);
}
return map;
}
常見頭信息介紹
-
HTTP狀態(tài)碼
- 1xx:信息響應(yīng)類,表示接收到請(qǐng)求并且繼續(xù)處理
- 2xx:處理成功響應(yīng)類,表示動(dòng)作被成功接收、理解和接受,常見為200
- 3xx:重定向響應(yīng)類,為了完成指定的動(dòng)作,必須接受進(jìn)一步處理
- 4xx:客戶端錯(cuò)誤,客戶請(qǐng)求包含語(yǔ)法錯(cuò)誤或者是不能正確執(zhí)行;常見的404錯(cuò)誤,就是找不到資源,趕緊檢查URL是否正確吧
- 5xx:服務(wù)端錯(cuò)誤,服務(wù)器不能正確執(zhí)行一個(gè)正確的請(qǐng)求;若見到500的錯(cuò)誤,則可以判斷是服務(wù)端處理存在問(wèn)題啦
Content-Type
表示后面的消息體屬于什么MIME類型。Java Servlet默認(rèn)為text/plain,但通常需要顯式地指定為text/html;而對(duì)基于Json的REST交互,則需要配置為application/json。類型和內(nèi)容不一致的話,則可能導(dǎo)致應(yīng)用收到消息后不能正常解析。
詳細(xì)取值范圍參考:http://www.runoob.com/http/http-content-type.htmlContent-Length
表示消息體的長(zhǎng)度。在服務(wù)聯(lián)調(diào)過(guò)程中,可能會(huì)出現(xiàn)網(wǎng)絡(luò)問(wèn)題或連接斷開導(dǎo)致消息傳遞不完整,這個(gè)時(shí)候通過(guò)該字段可以判斷消息體長(zhǎng)度和正常時(shí)是否一致來(lái)排查問(wèn)題。Accept
瀏覽器/客戶端告訴服務(wù)端自己接受的介質(zhì)類型(即Content-Type),/表示任何類型,type/*表示該類型下的所有子類型。Accept-Charset
瀏覽器/客戶端申明自己接受的字符集編碼。Date
表示消息發(fā)送的時(shí)間,時(shí)間的描述格式由RFC822定義。例如,Date: Fri, 06 Apr 2018 15:02:56 GMT。Date描述的時(shí)間表示世界標(biāo)準(zhǔn)時(shí)(即0時(shí)區(qū)),換算成本地時(shí)間需要知道用戶所在的時(shí)區(qū)。X-Forwarded-For
這是一個(gè)請(qǐng)求頭中的擴(kuò)展頭部,HTTP/1.1(RFC 2616)協(xié)議并沒(méi)有對(duì)它的定義,它最開始是由Squid這個(gè)緩存代理軟件引入,用來(lái)表示HTTP請(qǐng)求端真實(shí)IP。如今它已經(jīng)成為事實(shí)上的標(biāo)準(zhǔn),被各大HTTP代理、負(fù)載均衡等轉(zhuǎn)發(fā)服務(wù)廣泛使用,并被寫入RFC 7239(Forwarded HTTP Extension)標(biāo)準(zhǔn)之中。User-Agent
標(biāo)識(shí)請(qǐng)求者的一些信息,如什么瀏覽器類型和版本、操作系統(tǒng),使用語(yǔ)言等信息,例如:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36Cookie
HTTP請(qǐng)求發(fā)送時(shí),會(huì)把保存在該請(qǐng)求域名下的所有cookie值一起發(fā)送給web服務(wù)器。
設(shè)置頭信息
了解到以上內(nèi)容之后,根據(jù)開發(fā)需要可設(shè)置HTTP頭域的值,甚至可以設(shè)置一些自定義的頭域信息。例如:
public String getRuleList(HttpServletRequest request,
HttpServletResponse response) {
response.setHeader("content-type", "text/html;charset=UTF-8");
response.addHeader("test", "test"); //自定義
return service.getRuleList();
}
// Content-Type: text/html;charset=UTF-8
// test: test
參考資料: