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: 表示輸入框的類型. text 表示文本, password 表示密碼, submit 表示提交按鈕.
- name: 表示構(gòu)造出的 HTTP 請(qǐng)求的 query string 的 key. query string 的 value 就是輸入框的用戶輸入的內(nèi)容.
- value: input 標(biāo)簽的值. 對(duì)于 type 為 submit 類型來說, 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)求:

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

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

請(qǐng)求體為:

get方法同理,只是請(qǐng)求體中的數(shù)據(jù)去到了請(qǐng)求頭中變成查詢字符串了。
二、ajax構(gòu)造http請(qǐng)求
從前端角度, 除了瀏覽器地址欄能構(gòu)造 GET 請(qǐng)求, form 表單能構(gòu)造 GET 和 POST 之外, 還可以通過 ajax的方式來構(gòu)造 HTTP 請(qǐng)求. 并且功能更強(qiáng)大.
ajax 全稱 Asynchronous Javascript And XML, 是 2005 年提出的一種 JavaScript 給服務(wù)器發(fā)送
HTTP 請(qǐng)求的方式.
特點(diǎn)是可以不需要 刷新頁面/頁面跳轉(zhuǎn) 就能進(jìn)行數(shù)據(jù)傳輸.
在 JavaScript 中可以通過 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è)置要訪問的 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ū)分大小寫
console.log(this.responseText)
}
// 區(qū)別在這里, 調(diào)用 setRequestHeader 設(shè)置請(qǐng)求頭。設(shè)置類型是text類型, 也可以是application/x-www-form-urlencoded 類型
xhr.setRequestHeader('Content-Type', 'text/killingvibe')
// 4. 調(diào)用 send 方法發(fā)送 http 請(qǐng)求
xhr.send('我隨便寫,按照 content-type 的格式去寫就行')
地址欄輸入http://127.0.0.1:8080/ajax-send-request-body.html 后,打開網(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 中寫入一個(gè)字符串.
所謂的 “接受 HTTP 響應(yīng)”, 本質(zhì)上就是從 TCP Socket 中讀取一個(gè)字符串, 再按照 HTTP 的格式來解析.
我們基于 Socket 的知識(shí), 完全可以構(gòu)造出一個(gè)簡(jiǎn)單的 HTTP 客戶端程序, 用來發(fā)送各種類型的 HTTP 請(qǐng)求.
客戶端代碼:
public class MyHttpClient {
public static void main(String[] args) throws Exception {
// 只能進(jìn)行一次請(qǐng)求-響應(yīng)的 HTTP 客戶端
// 主機(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)求頭:完全可以沒有,但必須一個(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 是沒有請(qǐng)求體
// 最終的請(qǐng)求 —— 要發(fā)送給服務(wù)器的東西
String request = requestLine + requestHeader3;
// 發(fā)送服務(wù)器的過程
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)聽在 8080 端口上
try (ServerSocket serverSocket = new ServerSocket(8080)) {
while (true) {
Socket socket = serverSocket.accept(); // 三次握手完成
// 讀取用戶的請(qǐng)求 :咱這里就不管用戶的請(qǐng)求是啥了,一律采用相同的方式返回響應(yīng)
// 發(fā)送響應(yīng)
// Content-Type: 瀏覽器應(yīng)該按照什么格式來看到我們響應(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)體的類型
+ "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í)體類的問題
這篇文章主要介紹了springboot+mybatis報(bào)錯(cuò)找不到實(shí)體類的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
SpringBoot讀取自定義配置文件方式(properties,yaml)
這篇文章主要介紹了SpringBoot讀取自定義配置文件方式(properties,yaml),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
SpringBoot @PostConstruct原理用法解析
這篇文章主要介紹了SpringBoot @PostConstruct原理用法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08
springboot與數(shù)據(jù)庫返回?cái)?shù)據(jù)中文亂碼
大家好,本篇文章主要講的是springboot與數(shù)據(jù)庫返回?cái)?shù)據(jù)中文亂碼,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2022-01-01
淺談Android開發(fā)中項(xiàng)目的文件結(jié)構(gòu)及規(guī)范化部署建議
這篇文章主要介紹了Android開發(fā)中項(xiàng)目的文件結(jié)構(gòu)及規(guī)范化部署建議,組織好代碼文件的結(jié)構(gòu)有利于維護(hù)團(tuán)隊(duì)合作的效率,需要的朋友可以參考下2016-03-03
ThreadLocal內(nèi)存泄漏常見要點(diǎn)解析
這篇文章主要介紹了ThreadLocal內(nèi)存泄漏常見要點(diǎn),文中通過示例代碼介紹的非常詳細(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類支持五種UUID版本,每種具有不同的生成方式和使用場(chǎng)景,本文就來介紹一下如何使用,感興趣的可以了解一下2024-11-11
MyBatis自定義映射resultMap的實(shí)現(xiàn)
本文主要介紹了MyBatis自定義映射resultMap的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03

