Java URLConnection類 發送POST GET請求 及其實現原理雜談

回顧1【JAVA URLConnection 實現下載小文件

回顧2【Java使用socket通過http下載文件】裏面有關於http的比較基礎的知識

請求信息

無論POST還是GET請求,傳輸信息的核心思想就是 k-v,即 key-value , 【鍵-值】

以鍵值對的形式傳遞字符串信息,如下是一個鍵值對

key1=value1

多對鍵值,每隊之間用&隔開

key1=value1&key2=value2&key3=value3

GET請求如何攜帶信息

get請求可謂最常見的請求,瀏覽器默認發送的就是這個請求,get請求能夠向服務器請求指定位置的文件,或者是向服務器發送一些信息,這些信息夾帶在【請求信息】中,而get請求的信息夾帶方式十分簡單粗暴

GET的【請求信息】夾帶在url中,以?分割,比如向xxx.com發送請求信息:key1=value1&key2=value2&key3=value3,那麼夾帶信息的url就是:

http://www.xxx.com?key1=value1&key2=value2&key3=value3
  • 直接在url中夾帶信息可以使我們簡單粗暴的提交get請求

GET請求:代碼

String url = "http://www.xxx.com";	// 請求的url
String queryStr = "key1=value1&key2=value2&key3=value3";	// 請求信息

url += "?" + queryStr;	// 直接附加在url上即可
URLConnection con = new URL(url).openConnection();
con.connect();
String extension = '.' + con.getContentType().split("/")[1].split(";")[0];

// 獲取輸入流並寫入文件輸出流
InputStream is = con.getInputStream();
String loc = "E:/MyEclipse/WorkSpace/Hello/src/lab7/DownloadFiles/";
FileOutputStream fos = new FileOutputStream(loc + "123" + extension);

int len;
byte[] buf = new byte[1024];
while((len=is.read(buf)) != -1) {
	fos.write(buf, 0, len);
}
fos.close();
System.out.println("下載完成" + loc + "123" + extension);

POST請求如何攜帶信息

與get請求不同,POST請求不是明文提交,也就是url不會發生任何變化,取而代之,POST請求的信息寫在http的包內容裏面

比如提交請求信息:key1=value1&key2=value2&key3=value3

那麼實際上發送的信息是這樣的

POST url HTTP/1.1
......
......
......
http包頭結束

key1=value1&key2=value2&key3=value3	 <--這裏纔是夾帶請求信息的地方

POST請求:代碼

值得注意的是,如果使用POST請求,不僅要調用URLConnection對象的setDoOutput方法(要在調用connect方法之前設置),設置爲可以輸出(也就是可以傳輸協議正文內容,即我們的請求信息),還需要注意輸入輸出流的順序

因爲http每次只處理一次請求的特點,即處理完之後直接斷開,所以要注意輸入輸出流的順序,即向服務器輸出數據要在獲取服務器輸入數據之前

如圖:POST請求時序圖
在這裏插入圖片描述
代碼

String url = "http://www.xxx.com";	// 請求的url
String queryStr = "key1=value1&key2=value2&key3=value3";	// 請求信息

URLConnection con = new URL(url).openConnection();
con.setDoOutput(true);	// 設置請求爲可寫
con.connect();

// 輸出流寫http報內容
OutputStream os = con.getOutputStream();
os.write(queryStr.getBytes());	// 在http協議內容中發送post請求字符串
os.close();

// 獲取輸出流 即向服務器發送請求終止,然後等待服務器的回傳信息進而得到輸出流
// !!! 這個操作必須放在輸出流操作結束之後  !!!
InputStream is = con.getInputStream();

// 下載文件
String extension = '.' + con.getContentType().split("/")[1].split(";")[0];
String loc = "E:/MyEclipse/WorkSpace/Hello/src/lab7/DownloadFiles/";
FileOutputStream fos = new FileOutputStream(loc + "123" + extension);

int len;
byte[] buf = new byte[1024];
while((len=is.read(buf)) != -1) {
	fos.write(buf, 0, len);
}
fos.close();
System.out.println("下載完成" + loc + "123" + extension);

測試

測試的頁面我放在了我的個人網站上面,這裏是鏈接:
http://www.szulrl.cn/queryTest/index.php

將以下參數設置,然後使用上文的代碼可以發送GET請求

String url = "http://www.szulrl.cn/queryTest/index.php";
String queryStr = "key1=value1&key2=value2&key3=value3";

GET

文件下載成功
在這裏插入圖片描述
打開下載的html文件,查看下載的頁面的信息,可以看到請求是成功的
在這裏插入圖片描述

POST

文件下載成功
在這裏插入圖片描述
在這裏插入圖片描述

測試頁面源碼

需要放在有php的服務器環境下

<!DOCTYPE html>
<meta charset="utf-8">
<html>
<head>
	<title>請求測試</title>
	<style type="text/css">
		#title {
			display: inline-block;
			background-color: #0ff;
			width: 49%;
			height: 50px;
			line-height: 50px;
			font-size: 22px;
			text-align: center;
		}
		span {
			display: inline-block;
			width: 49%;
			height: 50px;
			line-height: 50px;
			font-size: 22px;
			text-align: center;
		}
	</style>
</head>
<body>
    <div style="text-align: center;"><h1> POST / GET 請求的測試 -- 互聯網編程實驗5測試用 </h1></div>
    <div style="text-align: center; color: red;">: 如果內容無法顯示,說明請求未發送或請求發送失敗</div>
    <br><hr><br>
	<div>
		<span id="title">GET請求:key</span>
        <span id="title">GET請求:value</span><br>
        <?php
            foreach($_GET as $k=>$v) {
                echo "<span>" . $k . "</span>";
                echo "<span>" . $v . "</span><br>";
            }
        ?>
	</div>
	<br><hr><br>
	<div>
		<span id="title">POST請求:key</span>
        <span id="title">POST請求:value</span>
        <?php
            foreach($_POST as $k=>$v) {
                echo "<span>" . $k . "</span>";
                echo "<span>" . $v . "</span><br>";
            }
        ?>
    </div>
    <br><hr><br>
    <div style="text-align: center;">@SZU @CSSE @LiRuoLong</div>
    <div style="display: inline-block; height: 100px;"></div>
</body>
</html>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章