通過Java代碼淺談HTTP協議


最近剛看了http協議,想寫點東西加深一下理解,如果哪兒寫錯了,請指正。

介紹

 HTTP是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫。它的發展是萬維網協會(World Wide Web Consortium)和Internet工作小組IETF(Internet Engineering Task Force)合作的結果,(他們)最終發布了一系列的RFC,RFC 1945定義了HTTP/1.0版本。其中最著名的就是RFC 2616。RFC 2616定義了今天普遍使用的一個版本——HTTP 1.1。

HTTP協議(HyperText Transfer Protocol,超文本傳輸協議)是用於從WWW服務器傳輸超文本到本地瀏覽器的傳送協議。它可以使瀏覽器更加高效,使網絡傳輸減少。它不僅保證計算機正確快速地傳輸超文本文檔,還確定傳輸文檔中的哪一部分,以及哪部分內容首先顯示(如文本先於圖形)等。

1.1 http請求模型

       

這樣就限制了使用HTTP協議,無法實現在客戶端沒有發起請求的時候,服務器將消息推送給客戶端.

1.2 工作流程

一次HTTP操作稱為一個事務,其工作過程可分為四步:

1)首先客戶機與服務器需要建立連接。只要單擊某個超級鏈接,HTTP的工作開始。

2)建立連接后,客戶機發送一個請求給服務器,請求方式的格式為:統一資源標識符(URL)、協議版本號,后邊是MIME信息包括請求修飾符、客戶機信息和可能的內容。

3)服務器接到請求后,給予相應的響應信息,其格式為一個狀態行,包括信息的協議版本號、一個成功或錯誤的代碼,后邊是MIME信息包括服務器信息、實體信息和可能的內容。

4)客戶端接收服務器所返回的信息通過瀏覽器顯示在用戶的顯示屏上,然后客戶機與服務器斷開連接。

如果在以上過程中的某一步出現錯誤,那么產生錯誤的信息將返回到客戶端,有顯示屏輸出。對於用戶來說,這些過程是由HTTP自己完成的,用戶只要用鼠標點擊,等待信息顯示就可以了。

2 利用java代碼測試各個協議頭

一個完整的http協議包括請求和響應,下面我們一一介紹:

2.1  請求篇

http請求由三部分組成,分別是:請求行、消息報頭、請求正文

請求行以一個方法符號開頭,以空格分開,后面跟着請求的URI和協議的版本,格式如下:Method Request-URI HTTP-Version CRLF  
其中 Method表示請求方法;Request-URI是一個統一資源標識符;HTTP-Version表示請求的HTTP協議版本;CRLF表示回車和換行(除了作為結尾的CRLF外,不允許出現單獨的CR或LF字符)。

請求方法(所有方法全為大寫)有多種,各個方法的解釋如下:
GET     請求獲取Request-URI所標識的資源
POST    在Request-URI所標識的資源后附加新的數據
HEAD    請求獲取由Request-URI所標識的資源的響應消息報頭
PUT     請求服務器存儲一個資源,並用Request-URI作為其標識
DELETE  請求服務器刪除Request-URI所標識的資源
TRACE   請求服務器回送收到的請求信息,主要用於測試或診斷
CONNECT 保留將來使用
OPTIONS 請求查詢服務器的性能,或者查詢與資源相關的選項和需求
應用舉例:
GET方法:在瀏覽器的地址欄中輸入網址的方式訪問網頁時,瀏覽器采用GET方法向服務器獲取資源,eg:GET /form.html HTTP/1.1 (CRLF)

POST方法要求被請求服務器接受附在請求后面的數據,常用於提交表單。
eg:POST /reg.jsp HTTP/ (CRLF)
Accept:image/gif,image/x-xbit,... (CRLF)
...
HOST:www.guet.edu.cn (CRLF)
Content-Length:22 (CRLF)
Connection:Keep-Alive (CRLF)
Cache-Control:no-cache (CRLF)
(CRLF)         //該CRLF表示消息報頭已經結束,在此之前為消息報頭
user=jeffrey&pwd=1234  //此行以下為提交的數據

HEAD方法與GET方法幾乎是一樣的,對於HEAD請求的回應部分來說,它的HTTP頭部中包含的信息與通過GET請求所得到的信息是相同的。利用這個方法,不必傳輸整個資源內容,就可以得到Request-URI所標識的資源的信息。該方法常用於測試超鏈接的有效性,是否可以訪問,以及最近是否更新。

我們運用命令行命令Telnet進行測試:

1. 使用telnet連接到HTTP服務器,如要從google上請求index.html頁面,首先要連接到服務器的80端口 

telnet www.google.cn 80
2. 現在已經連接上了服務器,發送http請求消息:
GET /index.html HTTP/1.1
connection: close
Host: www.google.cn
輸入上面內容后,連續敲入兩個回車,哈哈,是不是看到返回結果了。
這個請求的意思是:通過1.1版本協議請求index.html頁面;connection: close是實用短連接,即服務器返回后就斷開連接;Host字段知名頁面所在的主機名。
返回結果應該是這樣的:
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Date: Fri, 02 Jan 2009 12:26:17 GMT
Expires: -1
Content-Type: text/html; charset=GB2312
Set-Cookie: PREF=ID=7bbe374f53b6c6a8:NW=1:TM=1230899177:LM=1230899177:S=2EGHuZJnrtdQUB_A; expires=Sun, 02-Jan-2011 12:26:17 GMT; path=/; domain=.google.com
Server: gws
Transfer-Encoding: chunked
Connection: Close
這里有一個額外的CRLF
<html>
html數據
</html>

2、請求報頭后述
3、請求正文(略) 

2.2 響應篇

響應消息包括狀態行、若干頭部行和附屬體(html數據實體)。
  • 狀態行
狀態行包括:HTTP協議版本號、狀態碼、狀態碼的文本描述信息。如:HTTP/1.1 200 OK
狀態碼由一個三位數組成,狀態碼大體有5種含義:
1. 1xx。信息,請求收到,繼續處理。
2. 2xx。成功。200請求成功;206斷點續傳。
3. 3xx。重定向。一般跳轉到新的地址。
4. 4xx。客戶端錯誤。404文件不存在
5. 5xx。服務器錯誤。500內部錯誤。
 
常見狀態代碼、狀態描述、說明:
200 OK      //客戶端請求成功
400 Bad Request  //客戶端請求有語法錯誤,不能被服務器所理解
401 Unauthorized //請求未經授權,這個狀態代碼必須和WWW-Authenticate報頭域一起使用 
403 Forbidden  //服務器收到請求,但是拒絕提供服務
404 Not Found  //請求資源不存在,eg:輸入了錯誤的URL
500 Internal Server Error //服務器發生不可預期的錯誤
503 Server Unavailable  //服務器當前不能處理客戶端的請求,一段時間后可能恢復正常
eg:HTTP/1.1 200 OK (CRLF)
  • 頭部行
Set-Cookie:服務器設置客戶端Cookie。設置格式是name=value,設置多個參數時中間用分號隔開。Set-Cookie時還會用到幾個參數:PATH設置有效的路徑,DOMAIN設置cookie生效的域名,Expire設置cookie的有效時間,0表示關閉瀏覽器就失效。
Location:當服務器返回3xx重定向時,該參數實現重定向。廣告鏈接的跳轉就使用這種協議。
Content-Length:附屬體(數據實體)的長度

2.3 測試協議頭 ----響應頭

通過在服務器端設置響應頭,我們可以控制瀏覽器,在myeclipse搭建tomcat服務器我們簡單地對幾個進行了測試:

1,通知瀏覽器采用壓縮數據方式發送,測試content-encoding和content-length

 1         String data="aaaaaaaaaaa";
 2         System.out.print("原始數據大小:"+data.getBytes().length);
 3         ByteArrayOutputStream bout=new ByteArrayOutputStream();
 4         GZIPOutputStream gout=new GZIPOutputStream(bout);
 5         gout.write(data.getBytes());
 6         gout.close();
 7         
 8         byte gzip[]=bout.toByteArray();
 9         System.out.print("壓縮后數據大小:"+gzip.length);
10         response.setHeader("Content-Encoding", "gzip");
11         response.setHeader("Content-Length", gzip.length+"");
12         response.getOutputStream().write(gzip);

2,重定向 測試location

1         response.setStatus(302);
2         response.setHeader("Location","/web1/1.html");

3,通知瀏覽器以哪種方式打開數據 測試content-type

1         response.setHeader("content-type", "image/bmp");
2         InputStream in=this.getServletContext().getResourceAsStream("/1.bmp");
3         int len=0;
4         byte buffer[]=new byte[1024];
5         
6         OutputStream out=response.getOutputStream();
7         while((len=in.read(buffer))>0){
8             out.write(buffer,0,len);
9         }

4,定時刷新 跳轉 測試refresh  3秒后刷新 然后跳到百度首頁

1         response.setHeader("refresh", "3;url='http://uwww.baidu.com'");
2         String data="aaaaaaaaaaaaaa";
3         response.getOutputStream().write(data.getBytes());

5,下載方面的測試   content-disposition

1         response.setHeader("content-disposition","attachment;filename=2.bmp");
2         InputStream in=this.getServletContext().getResourceAsStream("/2.bmp");
3         int len=0;
4         byte buffer[]=new byte[1024];
5         
6         OutputStream out=response.getOutputStream();
7         while((len=in.read(buffer))>0){
8             out.write(buffer,0,len);
9         }

 

 

上面只是我的淺見,剛看完想寫個博客,有錯誤歡迎指正!謝謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM