**1. HTTP協議的定義**
WWW是以Internet作為傳輸媒介的一個應用系統,WWW網上基本的傳輸單位是Web網頁。WWW的工作是基于客戶機/服務器計算模型,由Web瀏覽器和Web服務器構成,即B/S結構,兩者之間采用超文本傳輸協議HTTP進行通信。
HTTP協議是基于TCP/IP協議之上的協議,是Web瀏覽器和Web服務器之間的應用層的協議,是通用的、無狀態的面向對象的協議。
如果要實現網絡互聯我們要思考兩個需要解決的技術問題:
第一:瀏覽器和服務器是通過什么來連接的。
第二:這種連接方式是怎么實現的。
通過Internet去發送到服務器當中,而Internet內部可以通過三種方式來實現發送信息和數據:
第一種:HTTP協議,也是在工作中最常用的,是建立在TCP/IP基礎上實現的。
第二種:FTP協議
第三種:TCP/IP協議,它也是最底層的協議,其它的方式必須是要通過它,但是要想實現這種協議必須要實現socket編程,這種方法是用來上傳一些比較大的文件,視頻,進行斷點續傳的操作。
**2. HTTP協議實例剖析**
客戶端連接服務器實現內部的原理如下:

流程分析:
第一步:在瀏覽器客戶端中得到用戶輸入的內容。
第二步:瀏覽器得到這個網址之后,內部會將這個域名發送到DNS上,進行域名解析。得到它的IP之后就會鏈接到指定的服務器上,假如服務器的地址是:221.104.13.32:80,從瀏覽器到服務器端口它使用到最底層的TCP/IP協議
第三步:實現TCP/IP協議用Socket來完成,使用了Socket的套接字。
第四步:服務器端的80端口監聽客戶端的鏈接,這樣客戶端到服務器就鏈接上了。
**HTTP請求體的內容介紹**

~~~
1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
2. <%String path = request.getContextPath();%>
3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
4. <html>
5. <head>
6. <title>測試HTTP協議體的內容</title>
7. <meta http-equiv="pragma" content="no-cache">
8. <meta http-equiv="cache-control" content="no-cache">
9. <meta http-equiv="expires" content="0">
10. <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
11. <meta http-equiv="description" content="This is my page">
12. <!-- <link rel="stylesheet" type="text/css" href="styles.css"> -->
13. </head>
14. <body>
15. <form name="form1" method="post" action="<%=path %>/LonginServlet">
16. 用戶名:
17. <input type="text" name="username" value="admin" /><br />
18. 密 碼:
19. <input type="password" name="password" value="123" /><br />
20. <input type="submit" name="submit" value="提交表單" />
21. </form>
22. </body>
23. </html>
~~~
~~~
1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
2. <%String path = request.getContextPath();%>
3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
4. <html>
5. <head>
6. <title>測試HTTP協議體的內容</title>
7. <meta http-equiv="pragma" content="no-cache">
8. <meta http-equiv="cache-control" content="no-cache">
9. <meta http-equiv="expires" content="0">
10. <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
11. <meta http-equiv="description" content="This is my page">
12. <!-- <link rel="stylesheet" type="text/css" href="styles.css"> -->
13. </head>
14. <body>
15. <form name="form1" method="post" action="<%=path %>/LonginServlet">
16. 用戶名:
17. <input type="text" name="username" value="admin" /><br />
18. 密 碼:
19. <input type="password" name="password" value="123" /><br />
20. <input type="submit" name="submit" value="提交表單" />
21. </form>
22. </body>
23. </html>
~~~
`<form name="form1" method="post" action="<%=path %>/LonginServlet">` 表單中方法為 post, 所以提交后會跳轉到 "<%=path %>/LonginServlet",轉換一下是:http://192.168.1.105:8080/MyHTTP/LonginServlet; 并調用 LonginServlet.java 的 doPost()方法.
**HTTP響應的內容介紹**

可以用 **HTTPWatch** 工具查一下,這個操作的過程, HTTPWatch 是IE 的一個插件,安裝后,用IE瀏覽器打開,查看---> 瀏覽欄 就可以看到這個HTTPWatch .

在這里面可以測試到響應時間,結果,頭部信息等信息.
在這里面有個 Cookies: JSESSIONIDSent
5444476F20784E44DECCC2900186336D
當用戶登錄時,點擊登錄按鈕后,可能等的時間比較長,就多點了幾次,這樣就多次登錄了. 服務器怎么判斷是哪個用戶呢? 所有在HTTP的協議體當中要把Cookies的JSESSIONID返回給客戶端,客戶端就知道是哪個用戶登錄了.
**HTTP返回請求數據的三種方式**
服務器接收到這些內容之后,并按照這些請求的路徑找到對應的頁面,進一步找到對應的網頁內容,返回給客戶端。
服務器返回客戶端的內容有三種方式:
1、以HTML代碼內容返回。
2、以XML字符串的形式返回,在以后的android開發中這種形式返回數據比較多。
3、以JSON對象形式返回,在網絡流量上考慮JSON要比XML方式要好一些,便于解析
### POST和GET提交數據
**1. POST和GET方式的定義**
1. HTTP-GET和HTTP-POST是使用HTTP的標準協議動詞,用于編碼和傳送變量名/變量值對參數,并且使用相關的請求語義。
2. 每個HTTP-GET和HTTP-POST都由一系列HTTP請求頭組成,這些請求頭定義了客戶端從服務器請求了什么,而響應則是由一系列HTTP請求數據和響應數據組成,如果請求成功則返回響應的數據。
3. HTTP-GET以使用MIME類型application/x-www-form-urlencoded的urlencoded文本的格式傳遞參數。Urlencoding是一種字符編碼,保證被傳送的參數由遵循規范的文本組成,例如一個空格的編碼是"%20"。附加參數還能被認為是一個查詢字符串。
4. 與HTTP-GET類似,HTTP-POST參數也是被URL編碼的。然而,變量名/變量值不作為URL的一部分被傳送,而是放在實際的HTTP請求消息內部被傳送。
**2. GET和POST之間的主要區別**
* 1、GET是從服務器上獲取數據,POST是向服務器傳送數據。
* 2、在客戶端, GET方式在通過URL提交數據,數據在URL中可以看到;POST方式,數據放置在HTML HEADER內提交
* 3、對于GET方式,服務器端用Request.QueryString獲取變量的值,對于POST方式,服務器端用Request.Form獲取提交的數據。
* 4、GET方式提交的數據最多只能有1024字節,而POST則沒有此限制
* 5、安全性問題。正如在(2)中提到,使用 GET 的時候,參數會顯示在地址欄上,而 POST 不會。所以,如果這些數據是中文數據而且是非敏感數據,那么使用 GET ;如果用戶輸入的數據不是中文字符而且包含敏感數據,那么還是使用 POST為好
**3. URL的定義和組成**
Uniform Resource Locator 統一資源定位符
URL的組成部分:http://www.mbalib.com/china/index.htm
http://:代表超文本傳輸協議
www:代表一個萬維網服務器
mbalib.com/:服務器的域名,或服務器名稱
China/:子目錄,類似于我們的文件夾
Index.htm:是文件夾中的一個文件
/china/index.htm統稱為URL路徑
**4. Java中HTTP編程接口**
Java中進行HTTP編程有如下的兩種方式:
標準的Java接口
標準Apache接口
**示例1: HTTP協議,Get方式從服務器獲得一張圖片,采用標準的Java接口**
1. 建立Java Project.
2. 工程目錄下新建目錄/libs,把工具包拷貝到該目錄下,選中包右鍵--->Build path--->Add to build path.
3. /src下新建一個包com.http.get,包下新建一個類文件 HttpUtils.java.
~~~
1. public class HttpUtils {
2. private static String URL_PATH = "http://192.168.1.105:8080/MyHTTP/pro1.png";
3. public HttpUtils() {
4. }
5. //從服務器得到流之后寫到本地磁盤
6. public static void saveImageToDisk() {
7. InputStream inputStream = getInputStream(); //從服務器讀到輸入流
8. byte[] data = new byte[1024];
9. int len = 0;
10. FileOutputStream fileOutputStream = null;
11. try {
12. fileOutputStream = new FileOutputStream("C:\\test.png");
13. //從輸入流中讀取數據的下一個字節。
14. while ((len = inputStream.read(data)) != -1) {
15. fileOutputStream.write(data, 0, len);
16. }
17. } catch (IOException e) {
18. // TODO Auto-generated catch block
19. e.printStackTrace();
20. } finally {
21. if (inputStream != null) {
22. try {
23. inputStream.close();
24. } catch (IOException e) {
25. // TODO Auto-generated catch block
26. e.printStackTrace();
27. }
28. }
29. if (fileOutputStream != null) {
30. try {
31. fileOutputStream.close();
32. } catch (IOException e) {
33. // TODO Auto-generated catch block
34. e.printStackTrace();
35. }
36. }
37. }
38. }
39.
40. /**
41. * 獲得服務器端的數據,以InputStream形式返回
42. * @return
43. */
44. public static InputStream getInputStream() {
45. InputStream inputStream = null;
46. HttpURLConnection httpURLConnection = null;
47. try {
48. URL url = new URL(URL_PATH);
49. if (url != null) {
50. //這個類就是客戶端與服務器建立連接的一個類
51. httpURLConnection = (HttpURLConnection) url.openConnection();
52. // 設置連接網絡的超時時間
53. httpURLConnection.setConnectTimeout(3000);
54. httpURLConnection.setDoInput(true); //從服務器取回數據
55. // 表示設置本次http請求使用GET方式請求
56. httpURLConnection.setRequestMethod("GET");
57. //從 HTTP 響應消息獲取狀態碼
58. int responseCode = httpURLConnection.getResponseCode();
59. if (responseCode == 200) {
60. // 從服務器獲得一個輸入流
61. inputStream = httpURLConnection.getInputStream();
62. }
63. }
64. } catch (MalformedURLException e) {
65. // TODO Auto-generated catch block
66. e.printStackTrace();
67. } catch (IOException e) {
68. // TODO Auto-generated catch block
69. e.printStackTrace();
70. }
71. return inputStream;
72. }
73. public static void main(String[] args) {
74. // 從服務器獲得圖片保存到本地
75. saveImageToDisk();
76. }
77. }
~~~
~~~
1. public class HttpUtils {
2. private static String URL_PATH = "http://192.168.1.105:8080/MyHTTP/pro1.png";
3. public HttpUtils() {
4. }
5. //從服務器得到流之后寫到本地磁盤
6. public static void saveImageToDisk() {
7. InputStream inputStream = getInputStream(); //從服務器讀到輸入流
8. byte[] data = new byte[1024];
9. int len = 0;
10. FileOutputStream fileOutputStream = null;
11. try {
12. fileOutputStream = new FileOutputStream("C:\\test.png");
13. //從輸入流中讀取數據的下一個字節。
14. while ((len = inputStream.read(data)) != -1) {
15. fileOutputStream.write(data, 0, len);
16. }
17. } catch (IOException e) {
18. // TODO Auto-generated catch block
19. e.printStackTrace();
20. } finally {
21. if (inputStream != null) {
22. try {
23. inputStream.close();
24. } catch (IOException e) {
25. // TODO Auto-generated catch block
26. e.printStackTrace();
27. }
28. }
29. if (fileOutputStream != null) {
30. try {
31. fileOutputStream.close();
32. } catch (IOException e) {
33. // TODO Auto-generated catch block
34. e.printStackTrace();
35. }
36. }
37. }
38. }
39.
40. /**
41. * 獲得服務器端的數據,以InputStream形式返回
42. * @return
43. */
44. public static InputStream getInputStream() {
45. InputStream inputStream = null;
46. HttpURLConnection httpURLConnection = null;
47. try {
48. URL url = new URL(URL_PATH);
49. if (url != null) {
50. //這個類就是客戶端與服務器建立連接的一個類
51. httpURLConnection = (HttpURLConnection) url.openConnection();
52. // 設置連接網絡的超時時間
53. httpURLConnection.setConnectTimeout(3000);
54. httpURLConnection.setDoInput(true); //從服務器取回數據
55. // 表示設置本次http請求使用GET方式請求
56. httpURLConnection.setRequestMethod("GET");
57. //從 HTTP 響應消息獲取狀態碼
58. int responseCode = httpURLConnection.getResponseCode();
59. if (responseCode == 200) {
60. // 從服務器獲得一個輸入流
61. inputStream = httpURLConnection.getInputStream();
62. }
63. }
64. } catch (MalformedURLException e) {
65. // TODO Auto-generated catch block
66. e.printStackTrace();
67. } catch (IOException e) {
68. // TODO Auto-generated catch block
69. e.printStackTrace();
70. }
71. return inputStream;
72. }
73. public static void main(String[] args) {
74. // 從服務器獲得圖片保存到本地
75. saveImageToDisk();
76. }
77. }
~~~
4. 把pro1.png圖片放在MyHTTP web工程目錄下,啟動服務器.
5. 運行這個Java工程,rus as--->Java Project.
然后就可這個 pro1.png 圖片下載到D:\test.png.
**期間,遇到一個錯誤,工程目錄上有個大大的紅色驚嘆號**。
后來找到原因是導入了多余的包,解決方法有兩種:
(1) library里導入了多余的包,刪除后就可以了
(2) 把java build path里面的libraries全部remove掉,再重新add進去就行了
你現在打開MyEclipse 右鍵單擊你的web工程,找到 Build Path > Configure Build Paht... > 然后上面有幾個選項卡找到 Libraries。 這里看到的就是你工程里面引用的 所有的 jar , 看看是不是在某個jar圖標上有個很小的黃色的感嘆號? 如果有的話就沒錯了, 先選中這個jar, 點擊右邊的 Remove > 點擊OK 等待幾秒,現在web工程上面的紅色XX是不是沒有了。