Http協議及get、post請求

https://www.cnblogs.com/qdhxhz/p/8468913.html

https://blog.csdn.net/a360316515/article/details/77272128

https://www.cnblogs.com/Garnett-Boy/p/8251561.html

HTTP協議是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫,是用於從萬維網(WWW:World Wide Web )服務器傳輸超文本到本地瀏覽器的傳送協議。HTTP是一個基於TCP/IP通信協議來傳遞數據(HTML 文件, 圖片文件, 查詢結果等)。HTTP協議工作於客戶端-服務端架構爲上。瀏覽器作爲HTTP客戶端通過URL向HTTP服務端即WEB服務器發送所有請求。Web服務器根據接收到的請求後,向客戶端發送響應信息。HTTP默認的端口號爲80,HTTPS的端口號爲443。
客戶端發送一個HTTP請求到服務器的請求消息包括以下格式:請求行、請求頭部、空行和請求數據四個部分組成。
服務器接收並處理客戶端發過來的請求後會返回一個HTTP的響應消息。HTTP響應也由四個部分組成,分別是:狀態行、消息報頭、空行和響應正文。
主要特點

1、簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規定了客戶與服務器聯繫的類型不同。由於HTTP協議簡單,使得HTTP服務器的程序規模小,因而通信速度很快。
2、靈活:HTTP允許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。
3.無連接:無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開連接。採用這種方式可以節省傳輸時間。
4.無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味着如果後續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時它的應答就較快。
5、支持B/S及C/S模式。

URL,全稱是UniformResourceLocator, 中文叫統一資源定位符,是互聯網上用來標識某一處資源的地址。URL一般由三部組成:①協議(或稱爲服務方式)②存有該資源的主機IP地址(有時也包括端口號)③主機資源的具體地址。如目錄和文件名等。
以下面這個URL爲例,介紹下普通URL的各部分組成:
http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name
從上面的URL可以看出,一個完整的URL包括以下幾部分:
1.協議部分:該URL的協議部分爲“http:”,這代表網頁使用的是HTTP協議。在Internet中可以使用多種協議,如HTTP,FTP等等本例中使用的是HTTP協議。在"HTTP"後面的“//”爲分隔符
2.域名部分:該URL的域名部分爲“www.aspxfans.com”。一個URL中,也可以使用IP地址作爲域名使用
3.端口部分:跟在域名後面的是端口,域名和端口之間使用“:”作爲分隔符。端口不是一個URL必須的部分,如果省略端口部分,將採用默認端口
4.虛擬目錄部分:從域名後的第一個“/”開始到最後一個“/”爲止,是虛擬目錄部分。虛擬目錄也不是一個URL必須的部分。本例中的虛擬目錄是“/news/”
5.文件名部分:從域名後的最後一個“/”開始到“?”爲止,是文件名部分,如果沒有“?”,則是從域名後的最後一個“/”開始到“#”爲止,是文件部分,如果沒有“?”和“#”,那麼從域名後的最後一個“/”開始到結束,都是文件名部分。本例中的文件名是“index.asp”。文件名部分也不是一個URL必須的部分,如果省略該部分,則使用默認的文件名
6.錨部分:從“#”開始到最後,都是錨部分。本例中的錨部分是“name”。錨部分也不是一個URL必須的部分
7.參數部分:從“?”開始到“#”爲止之間的部分爲參數部分,又稱搜索部分、查詢部分。本例中的參數部分爲“boardID=5&ID=24618&page=1”。參數可以允許有多個參數,參數與參數之間用“&”作爲分隔符。
    HTTP協議中定義了瀏覽器和服務器進行交互的不同方法,基本方法有4種,分別是GET,POST,PUT,DELETE。這四種方法可以理解爲,對服務器資源的查,改,增,刪。
GET:從服務器上獲取數據,也就是所謂的查,僅僅是獲取服務器資源,不進行修改。
POST:向服務器提交數據,這就涉及到了數據的更新,也就是更改服務器的數據。
PUT:PUT的英文含義是放置,也就是向服務器新添加數據,就是所謂的增。
DELETE:從字面意思也能看出,這種方式就是刪除服務器數據的過程。
POST和GET方式的安全性是相對的,另外也要看是從哪個角度來看的。從數據傳輸過程方面來看,POST方式是更加安全的,但是從對服務器數據的操作來看,POST方式的安全性又是比較低的。

GET和POST請求方式的區別:
1、GET請求的數據會暴露在地址欄中,而POST請求則不會
GET請求,請求的數據會附加在URL之後,以?分割URL和傳輸數據,多個參數用&連接。URL的編碼格式採用的是ASCII編碼,而不是uniclde,即是說所有的非ASCII字符都要編碼之後再傳輸。
POST請求:POST請求會把請求的數據放置在HTTP請求包的包體中。上面的item=bandsaw就是實際的傳輸數據。
2、傳輸數據的大小
在HTTP規範中,沒有對URL的長度和傳輸的數據大小進行限制。但是在實際開發過程中,對於GET,特定的瀏覽器和服務器對URL的長度有限制。因此,在使用GET請求時,傳輸數據會受到URL長度的限制。
對於POST,由於不是URL傳值,理論上是不會受限制的,但是實際上各個服務器會規定對POST提交數據大小進行限制,Apache、IIS都有各自的配置。
3、安全性
POST的安全性比GET的高。這裏的安全是指真正的安全,而不同於上面GET提到的安全方法中的安全,上面提到的安全僅僅是不修改服務器的數據。比如,在進行登錄操作,通過GET請求,用戶名和密碼都會暴露再URL上,因爲登錄頁面有可能被瀏覽器緩存以及其他人查看瀏覽器的歷史記錄的原因,此時的用戶名和密碼就很容易被他人拿到了。除此之外,GET請求提交的數據還可能會造成Cross-site request frogery攻擊
4、HTTP中的GET,POST,SOAP協議都是在HTTP上運行的

GET方式:
1、GET方式是以實體的方式得到由請求URL所指定資源的信息,如果請求URL只是一個數據產生過程,那麼最終要在響應實體中返回的是處理過程的結果所指向的資源,而不是處理過程的描述。也就是說,GET得到的信息是資源,而不是資源的處理過程。
2、請求的數據會附加在URL之後,以?分隔URL和傳輸數據,多個參數用&連接。URL編碼格式採用的是ASCII編碼,而不是Unicode,即所有的非ASCII字符都要編碼之後再傳輸。
3、因爲URL的長度限制,GET方式傳輸的數據大小有所限制,傳送的數據量不超過2KB。
4、GET方式服務器端用Request.QueryString獲取變量的值。
5、GET方式傳輸的參數安全性低,因爲傳輸的數據會顯示在請求的URL中。
POST方式:
1、用來向目的服務器發出請求,要求它接收被附在請求後的實體,並把它當做請求隊列中請求URL所指定資源的附加新子項。
2、POST方式將表單內各個字段和內容放置在HTML HEADER中一起傳送到Action屬性所指定的URL地址,用戶是看不到這個過程的。
3、POST方式傳送的數據量比較大,一般被默認爲沒有限制,但是根據IIS的配置,傳輸量也是不同的。
4、POST方式在服務器端用Request.Form獲取提交的數據。

5、POST方式傳輸的數據安全性較高,因爲數據傳輸不是明顯顯示的。

HTTPS(全稱:Hypertext Transfer Protocol over Secure Socket Layer),是以安全爲目標的HTTP通道,簡單講是HTTP的安全版。URL表明它使用了HTTP,但HTTPS存在不同於HTTP的默認端口及一個加密/身份驗證層(在HTTP與TCP之間)。,HTTPS在HTTP的基礎上加入了SSL協議,SSL依靠證書來驗證服務器的身份,併爲瀏覽器和服務器之間的通信加密。HTTPS協議的主要作用可以分爲兩種:(1)確認通訊雙方的身份,(2)建立安全通道,保證數據傳輸安全。
HTTPS和HTTP的區別主要如下:
  1、https協議需要到ca申請證書,一般免費證書較少,因而需要一定費用。
  2、http是超文本傳輸協議,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協議。
  3、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,後者是443。

  4、http的連接很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,比http協議安全。

SSL 協議既用到了公鑰加密技術(非對稱加密),又用到了對稱加密技術。
Step 1:用公開密鑰加密技術(通常爲RSA)驗證彼此身份(有時服務器不需要驗證客戶端身份),並協商Step2中通訊時所用的對稱加密密鑰;
Step 2:用對稱密鑰加密技術(如DES,或者RC4)加密服務器端和客戶端通訊時的數據。
這樣做的好處是:公開密鑰加密相對複雜,速度慢,可用來完成安全性要求較高的身份認證、密鑰協商等事務;對稱密鑰加密技術相對簡單,速度快,可用來加密數據量大的傳輸內容。

HttpUrlConnection 與httpClient

在java中連接http,介紹兩種方法,一種是java的HttpUrlConnection,另一種是apacha公司的httpClient,後者是第三方的類庫需要從外部,導入,同時這也是第一次使用外部的類庫,以後還會有很多需要導入外部類庫的需求。
http協議是基於tcp的一種協議。
tcp是一種保證可靠連接的傳輸協議,通過三次握手,和丟失重傳的機制保證數據的傳輸。

首先來看HttpUrlConnection

這個類是java自帶的,直接import就行。
使用tcp連接的過程幾乎都一樣,http協議中有兩種方式,一種是get方式,另一種是post提交,有些網頁需要提交數據,所以要使用。

先看GET

首先需要一個url,這個url使用String建立

String path ="";//
URL url = new URL(path);

之後通過url對象打開連接

HttpURLConnection  conn = (HttpURLConnection) url.openConnection();

這裏需要注意打開連接之後,這個函數返回的是不是httpUrlconnection類型而是 URLConnection類型,可以直接強轉。
之後開始通過對conn對象進行設置連接的參數

conn.setRequestMethod("GET");   //設置本次請求的方式 , 默認是GET方式, 參數要求都是大寫字母
            conn.setConnectTimeout(5000);//設置連接超時
            conn.setDoInput(true);//是否打開輸入流 , 此方法默認爲true
            conn.setDoOutput(true);//是否打開輸出流, 此方法默認爲false
            conn.connect();//表示連接

之後就開始判斷是否連接成功,服務器會返回一個響應碼,最常見的大概就是我們的404,不過除此之外還有很多,而成功連接返回的是200,也有一個靜態的名稱來代替HTTP_OK。
可以使用一個if判斷:

int code = conn.getResponseCode();    // 獲取服務器的響應代碼。
String getResponseMessage(); // 獲取服務器的響應消息。
String getResponseMethod(); // 獲取發送請求的方法。

當我們確定連接成功之後,我們就需要打開服務器的輸出流,然後從這個流裏讀取數據

    InputStream  is = conn.getInputStream();

                String name = path.substring(path.lastIndexOf("/")+1);

                System.out.println("name = " + name);

               fos = new FileOutputStream("C:\\pro\\"+name);

                byte[] buffer = new byte[1024];
                int len = 0;

                while ((len = is.read(buffer))!=-1) {

                    fos.write(buffer, 0, len);

這裏通過getinputStream得到流,然後通過FileOutputStream流將文件寫入到c盤。至此下載文件結束。

下面是post

與get相比,就是在設置請求方式的時候設置爲POST,然後提交要提交的數據

OutputStream os = conn.getOutputStream();
        os.write("platform=2&appVersion=1.7.0&osType=2".getBytes());
        os.flush();

得到了服務器的輸出流,然後寫入數據,以&分隔。 除此之外,完全一樣。

  • HttpURLConnection對象不能直接構造,需要通過URL類中的openConnection()方法來獲得。
  • HttpURLConnection的connect()函數,實際上只是建立了一個與服務器的TCP連接,並沒有實際發送HTTP請求。HTTP請求實際上直到我們獲取服務器響應數據(如調用getInputStream()、getResponseCode()等方法)時才正式發送出去。
  • 對HttpURLConnection對象的配置都需要在connect()方法執行之前完成。
  • HttpURLConnection是基於HTTP協議的,其底層通過socket通信實現。如果不設置超時(timeout),在網絡異常的情況下,可能會導致程序僵死而不繼續往下執行。
  • HTTP正文的內容是通過OutputStream流寫入的, 向流中寫入的數據不會立即發送到網絡,而是存在於內存緩衝區中,待流關閉時,根據寫入的內容生成HTTP正文。
  • 調用getInputStream()方法時,返回一個輸入流,用於從中讀取服務器對於HTTP請求的返回信息。
  • 我們可以使用HttpURLConnection.connect()方法手動的發送一個HTTP請求,但是如果要獲取HTTP響應的時候,請求就會自動的發起,比如我們使用HttpURLConnection.getInputStream()方法的時候,所以完全沒有必要調用connect()方法。

HttpClient

HttpClient就是一個增強版的HttpURLConnection
  1. 創建HttpClient對象。
  2. 如果需要發送GET請求,創建HttpGet對象;如果需要發送POST請求,創建HttpPost對象。
  3. 如果需要發送請求參數,可調用HttpGet、HttpPost共同的setParams(HttpParams params)方法來添加請求參數;對於HttpPost對象而言,也可調用setEntity(HttpEntity entity)方法來設置請求參數。
  4. 調用HttpClient對象的execute(HttpUriRequest request)發送請求,執行該方法返回一個HttpResponse。
  5. 調用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可獲取服務器的響應頭;調用HttpResponse的getEntity()方法可獲取HttpEntity對象,該對象包裝了服務器的響應內容。程序可通過該對象獲取服務器的響應內容。

首先我們需要導入第三方的類庫
第一部肯定是需要下載HttpClient的jar包。
這裏寫圖片描述
得到像這樣的3個jar包,然後再項目中新建一個libs的文件夾,將這三個jar包複製進去
這裏寫圖片描述
選中這三個包,然後右鍵,點擊Bulid Path就可以了
導入了包之後,就可以使用HttpClient類了
首先還是需要一個url

String path = "";

然後創建一個HttpClient對象

HttpClient client = new DefaultHttpClient();

之後創建一個GET請求對象

HttpGet httpGet = new HttpGet(path);

之後通過Client的execute函數來連接

HttpResponse response = client.execute(httpGet);

參數是get請求對象,返回的是一個httpresponse對象,這個對象,就是我們得到得結果,然後我們對這個response操作
同樣,先判斷一下響應碼

response.getStatusLine().getStatusCode() == 200;

這裏首先得到狀態行,然後再得到裏面的狀態碼。
我們通過這個Response可以得到一個實體HttpEntity。

HttpEntity entity = response.getEntity();

從這個實體中我們可以像上面一樣得到一個流使用getContent(),不過,這個類爲我們提供了更加簡單的方法,在EntityUtils類中有toByteArray(entity),和toString(entity)方法,返回的分別是byte[],和string,對於byte數組,我們可以使用FileOutputStream來寫入文件流中。

Post方式

和上面一樣,只是多出了一些操作部分

HttpPost httpPost = new HttpPost(path);

        //創建一個提交數據的容器
        List<BasicNameValuePair> parames = new ArrayList<>();

        parames.add(new BasicNameValuePair("platform", "2"));
        parames.add(new BasicNameValuePair("appVersion", "1.7.0"));
        parames.add(new BasicNameValuePair("osType", "2"));

        //封裝容器到請求參數中
        HttpEntity entity = new UrlEncodedFormEntity(parames);
        //設置請求參數到post請求中
        httpPost.setEntity(entity);

        //執行post請求
        HttpResponse response = client.execute(httpPost);
這裏的的類型變成了HttpPost,然後將post的參數加到容器裏,然後將容器傳給一個實體,將這個請求給post,之後執行。


發佈了40 篇原創文章 · 獲贊 11 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章