java構(gòu)造http請(qǐng)求的幾種方式(附源碼)
一、form表單構(gòu)造http請(qǐng)求
form (表單) 是 HTML 中的一個(gè)常用標(biāo)簽. 可以用于給服務(wù)器發(fā)送 GET 或者 POST 請(qǐng)求.
form 的重要參數(shù):
- action: 構(gòu)造的 HTTP 請(qǐng)求的 URL 是什么.
- method: 構(gòu)造的 HTTP 請(qǐng)求的 方法 是 GET 還是 POST (form 只支持 GET 和 POST).
input 的重要參數(shù):
- type: 表示輸入框的類(lèi)型. text 表示文本, password 表示密碼, submit 表示提交按鈕.
- name: 表示構(gòu)造出的 HTTP 請(qǐng)求的 query string 的 key. query string 的 value 就是輸入框的用戶(hù)輸入的內(nèi)容.
- value: input 標(biāo)簽的值. 對(duì)于 type 為 submit 類(lèi)型來(lái)說(shuō), value 就對(duì)應(yīng)了按鈕上顯示的文本.
<form method="get" action="/collect">
<input type="text" name="today">
<input type="text" name="result">
<button>提交</button>
</form>
<form method="post" action="/collect">
<input type="text" name="today">
<input type="text" name="result">
<button>提交</button>
</form>
以下是/collect資源,支持get和post請(qǐng)求:

打開(kāi)所在的頁(yè)面,輸入,并點(diǎn)擊提交(以post為例子):

打開(kāi)開(kāi)發(fā)者工具的網(wǎng)絡(luò)面板可以觀察到:
請(qǐng)求頭和響應(yīng)頭為:

請(qǐng)求體為:

get方法同理,只是請(qǐng)求體中的數(shù)據(jù)去到了請(qǐng)求頭中變成查詢(xún)字符串了。
二、ajax構(gòu)造http請(qǐng)求
從前端角度, 除了瀏覽器地址欄能構(gòu)造 GET 請(qǐng)求, form 表單能構(gòu)造 GET 和 POST 之外, 還可以通過(guò) ajax的方式來(lái)構(gòu)造 HTTP 請(qǐng)求. 并且功能更強(qiáng)大.
ajax 全稱(chēng) Asynchronous Javascript And XML, 是 2005 年提出的一種 JavaScript 給服務(wù)器發(fā)送
HTTP 請(qǐng)求的方式.
特點(diǎn)是可以不需要 刷新頁(yè)面/頁(yè)面跳轉(zhuǎn) 就能進(jìn)行數(shù)據(jù)傳輸.
在 JavaScript 中可以通過(guò) ajax 的方式構(gòu)造 HTTP 請(qǐng)求.
<!DOCTYPE html>
<html lang="zh-hans">
<head>
<meta charset="UTF-8">
<title>發(fā)送有請(qǐng)求體的 ajax 請(qǐng)求</title>
</head>
<body>
<script src="/js/ajax-send-request-body.js"></script>
</body>
</html>
以下是js代碼:
// 1. 創(chuàng)建 XMLHttpRequest 對(duì)象
var xhr = new XMLHttpRequest()
// 2. 調(diào)用 open 方法設(shè)置要訪問(wèn)的 url
xhr.open('post', '/collect')
// 3. 默認(rèn)異步處理響應(yīng). 需要掛在處理響應(yīng)的回調(diào)函數(shù).
xhr.onload = function() {
console.log(xhr)
console.log(this)
console.log(this.status)
console.log(this.getResponseHeader('location')) // header 中的 name 不區(qū)分大小寫(xiě)
console.log(this.responseText)
}
// 區(qū)別在這里, 調(diào)用 setRequestHeader 設(shè)置請(qǐng)求頭。設(shè)置類(lèi)型是text類(lèi)型, 也可以是application/x-www-form-urlencoded 類(lèi)型
xhr.setRequestHeader('Content-Type', 'text/killingvibe')
// 4. 調(diào)用 send 方法發(fā)送 http 請(qǐng)求
xhr.send('我隨便寫(xiě),按照 content-type 的格式去寫(xiě)就行')
地址欄輸入http://127.0.0.1:8080/ajax-send-request-body.html 后,打開(kāi)網(wǎng)絡(luò)面板,我們可以看到三個(gè)請(qǐng)求包,

拓展:
發(fā)送 application/json 數(shù)據(jù),只需要將上述代碼下面改成如下:
// 調(diào)用 setRequestHeader 設(shè)置請(qǐng)求頭
httpRequest.setRequestHeader('Content-Type', 'application/json');
// 4. 調(diào)用 send 方法發(fā)送 http 請(qǐng)求
httpRequest.send(JSON.stringify({
name: 'zhangsan',
age: 18
}));
三、Java socket構(gòu)造http請(qǐng)求
所謂的 “發(fā)送 HTTP 請(qǐng)求”, 本質(zhì)上就是按照 HTTP 的格式往 TCP Socket 中寫(xiě)入一個(gè)字符串.
所謂的 “接受 HTTP 響應(yīng)”, 本質(zhì)上就是從 TCP Socket 中讀取一個(gè)字符串, 再按照 HTTP 的格式來(lái)解析.
我們基于 Socket 的知識(shí), 完全可以構(gòu)造出一個(gè)簡(jiǎn)單的 HTTP 客戶(hù)端程序, 用來(lái)發(fā)送各種類(lèi)型的 HTTP 請(qǐng)求.
客戶(hù)端代碼:
public class MyHttpClient {
public static void main(String[] args) throws Exception {
// 只能進(jìn)行一次請(qǐng)求-響應(yīng)的 HTTP 客戶(hù)端
// 主機(jī) 127.0.0.1
// 端口(進(jìn)程) 8080
// 資源路徑 /hello.html
try (Socket socket = new Socket("127.0.0.1", 8080)) {
// 準(zhǔn)備 HTTP 請(qǐng)求內(nèi)容
// 文本 String
// 格式:請(qǐng)求行
String requestLine = "GET /hello.html HTTP/1.0\r\n";
// 請(qǐng)求頭:完全可以沒(méi)有,但必須一個(gè)空行結(jié)尾
String requestHeader1 = "Name: killingvibe\r\n\r\n"; // 請(qǐng)求頭中共有 1對(duì) key-value
String requestHeader2 = "Name: killingvibe\r\nAge: 1999\r\n\r\n"; // 請(qǐng)求頭中共有 2對(duì) key-value
String requestHeader3 = "\r\n"; // 請(qǐng)求頭中共有 0 對(duì) key-value
// 請(qǐng)求體,GET 是沒(méi)有請(qǐng)求體
// 最終的請(qǐng)求 —— 要發(fā)送給服務(wù)器的東西
String request = requestLine + requestHeader3;
// 發(fā)送服務(wù)器的過(guò)程
byte[] requestBytes = request.getBytes("ISO-8859-1"); // 字符集編碼
// 發(fā)送(數(shù)據(jù)會(huì)經(jīng)由 TCP、IP、以太網(wǎng)發(fā)送給服務(wù)器)
OutputStream os = socket.getOutputStream();
os.write(requestBytes);
os.flush();
// 請(qǐng)求既然已經(jīng)發(fā)送,我們要做的就是等待響應(yīng)
InputStream is = socket.getInputStream();
Scanner scanner = new Scanner(is, "UTF-8"); // 響應(yīng)的前面字符集應(yīng)該是 ISO-8859-1,后邊是 UTF-8
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(line);
}
}
}
}
服務(wù)端代碼:
public class MyHttpServer {
public static void main(String[] args) throws Exception {
// 我們也監(jiān)聽(tīng)在 8080 端口上
try (ServerSocket serverSocket = new ServerSocket(8080)) {
while (true) {
Socket socket = serverSocket.accept(); // 三次握手完成
// 讀取用戶(hù)的請(qǐng)求 :咱這里就不管用戶(hù)的請(qǐng)求是啥了,一律采用相同的方式返回響應(yīng)
// 發(fā)送響應(yīng)
// Content-Type: 瀏覽器應(yīng)該按照什么格式來(lái)看到我們響應(yīng)的資源內(nèi)容的(資源內(nèi)容放在響應(yīng)體中)
// 響應(yīng)體(資源的內(nèi)容)
String responseBody = "<h1>Welcome MyHttpServer</h1>";
byte[] responseBodyBytes = responseBody.getBytes("UTF-8");
int contentLength = responseBodyBytes.length;
System.out.println("發(fā)送響應(yīng)");
String response = "HTTP/1.0 200 OK\r\n"
+ "Server: killingvibeServer\r\n"
+ "Content-Type: text/plain; charset=utf-8\r\n" // 響應(yīng)體的類(lèi)型
+ "Content-Length: " + contentLength + "\r\n" // 響應(yīng)體的長(zhǎng)度
+ "\r\n";
byte[] responseBytes = response.getBytes("ISO-8859-1");
OutputStream os = socket.getOutputStream();
// TCP 是面向字節(jié)流的一種協(xié)議,所以只要按順序發(fā)即可,不要管分幾次發(fā)送
os.write(responseBytes); // 先發(fā)送前面部分(響應(yīng)行 和 響應(yīng)頭)
os.write(responseBodyBytes); // 再發(fā)送響應(yīng)體
os.flush();
// 發(fā)送完成之后,直接關(guān)閉 TCP 連接(短連接的處理模式)
socket.close();
}
}
}
}
控制臺(tái)打印如下:

總結(jié)
到此這篇關(guān)于java構(gòu)造http請(qǐng)求的幾種方式(附源碼)的文章就介紹到這了,更多相關(guān)java構(gòu)造http請(qǐng)求內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Servlet簡(jiǎn)單實(shí)現(xiàn)登錄功能
這篇文章主要為大家詳細(xì)介紹了Servlet簡(jiǎn)單實(shí)現(xiàn)登錄功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03
springboot+mybatis報(bào)錯(cuò)找不到實(shí)體類(lèi)的問(wèn)題
這篇文章主要介紹了springboot+mybatis報(bào)錯(cuò)找不到實(shí)體類(lèi)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
SpringBoot讀取自定義配置文件方式(properties,yaml)
這篇文章主要介紹了SpringBoot讀取自定義配置文件方式(properties,yaml),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
SpringBoot @PostConstruct原理用法解析
這篇文章主要介紹了SpringBoot @PostConstruct原理用法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08
springboot與數(shù)據(jù)庫(kù)返回?cái)?shù)據(jù)中文亂碼
大家好,本篇文章主要講的是springboot與數(shù)據(jù)庫(kù)返回?cái)?shù)據(jù)中文亂碼,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2022-01-01
淺談Android開(kāi)發(fā)中項(xiàng)目的文件結(jié)構(gòu)及規(guī)范化部署建議
這篇文章主要介紹了Android開(kāi)發(fā)中項(xiàng)目的文件結(jié)構(gòu)及規(guī)范化部署建議,組織好代碼文件的結(jié)構(gòu)有利于維護(hù)團(tuán)隊(duì)合作的效率,需要的朋友可以參考下2016-03-03
ThreadLocal內(nèi)存泄漏常見(jiàn)要點(diǎn)解析
這篇文章主要介紹了ThreadLocal內(nèi)存泄漏常見(jiàn)要點(diǎn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11
Java UUID 五個(gè)版本的區(qū)別及使用場(chǎng)景小結(jié)
在Java中,UUID是一個(gè)128位的唯一標(biāo)識(shí)符,廣泛應(yīng)用于生成唯一標(biāo)識(shí)符、分布式系統(tǒng)唯一鍵等場(chǎng)景,Java提供的java.util.UUID類(lèi)支持五種UUID版本,每種具有不同的生成方式和使用場(chǎng)景,本文就來(lái)介紹一下如何使用,感興趣的可以了解一下2024-11-11
MyBatis自定義映射resultMap的實(shí)現(xiàn)
本文主要介紹了MyBatis自定義映射resultMap的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03

