偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

面試官:請(qǐng)用Java實(shí)現(xiàn)一個(gè)HTTP請(qǐng)求

開發(fā) 前端
今天將介紹一種在 Java 中執(zhí)行 HTTP 請(qǐng)求的方法 -- 通過使用 Java 內(nèi)置的 HttpUrlConnection 類實(shí)現(xiàn)。

大家好,我是指北君。

最近面試的時(shí)候,竟然有面試官提出這樣的要求:請(qǐng)用Java實(shí)現(xiàn)一個(gè)HTTP請(qǐng)求!當(dāng)然不能慫! 雄起!!!

今天將介紹一種在 Java 中執(zhí)行 HTTP 請(qǐng)求的方法 -- 通過使用 Java 內(nèi)置的 HttpUrlConnection 類實(shí)現(xiàn)。

從 JDK 11 開始,Java 為執(zhí)行 HTTP 請(qǐng)求提供了一個(gè)新的 API,它是用來替代 HttpUrlConnection 的,即HttpClient API。

HttpUrlConnection

HttpUrlConnection 類允許我們執(zhí)行基本的 HTTP 請(qǐng)求,而無需使用任何額外的庫。我們需要的所有類都是 java.net 包的一部分。

使用這種方法的缺點(diǎn)是,代碼可能比其他的HTTP庫更繁瑣,而且它不提供更高級(jí)的功能,如添加頭文件或認(rèn)證的專用方法。

創(chuàng)建一個(gè)請(qǐng)求

我們可以使用 URL 類的 openConnection() 方法創(chuàng)建一個(gè) HttpUrlConnection 實(shí)例。注意,這個(gè)方法只是創(chuàng)建一個(gè)連接對(duì)象,但還沒有建立連接。

HttpUrlConnection 類通過將 requestMethod 屬性設(shè)置為get, post, head, options, put, delete, trace其中一個(gè)值。

讓我們使用GET方法創(chuàng)建一個(gè)與給定URL的連接:

URL url = new URL("https://www.javanorth.cn");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");

添加請(qǐng)求參數(shù)

如果我們想向一個(gè)請(qǐng)求添加參數(shù),我們必須將 doOutput 屬性設(shè)置為 true,然后向 HttpUrlConnection 實(shí)例的OutputStream 寫一個(gè)類似 param1=value&m2=value 的字符串。

Map<String, String> parameters = new HashMap<>();
parameters.put("param1", "val");

con.setDoOutput(true);
DataOutputStream out = new DataOutputStream(con.getOutputStream());
out.writeBytes(ParameterStringBuilder.getParamsString(parameters));
out.flush();
out.close();

為了方便參數(shù)Map的轉(zhuǎn)換,我們編寫了一個(gè)名為ParameterStringBuilder的實(shí)用類,其中包含一個(gè)靜態(tài)方法getParamsString(),可以將Map轉(zhuǎn)換為所需格式的字符串。

public class ParameterStringBuilder {
public static String getParamsString(Map<String, String> params)
throws UnsupportedEncodingException{
StringBuilder result = new StringBuilder();

for (Map.Entry<String, String> entry : params.entrySet()) {
result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
result.append("&");
}

String resultString = result.toString();
return resultString.length() > 0 ? resultString.substring(0, resultString.length() - 1) : resultString;
}
}

設(shè)置請(qǐng)求頭信息

通過使用 setRequestProperty() 方法可以實(shí)現(xiàn)在請(qǐng)求中添加頭信息。

con.setRequestProperty("Content-Type", "application/json");

要從一個(gè)連接中讀取一個(gè)頭的值,我們可以使用 getHeaderField() 方法。

String contentType = con.getHeaderField("Content-Type");

配置超時(shí)

HttpUrlConnection 類允許設(shè)置連接和讀取超時(shí)。這些值定義了等待與服務(wù)器的連接建立或數(shù)據(jù)可被讀取的時(shí)間間隔。

為了設(shè)置超時(shí)值,我們可以使用 setConnectTimeout()和 setReadTimeout()方法。

con.setConnectTimeout(5000);
con.setReadTimeout(5000);

在這個(gè)例子中,我們把兩個(gè)超時(shí)值都設(shè)為5秒。

處理Cookie

java.net 包包含了便于處理 cookie 的類,如 CookieManager 和 HttpCookie。

首先,為了從響應(yīng)中讀取 cookie,我們可以檢索 Set-Cookie 頭的值,并將其解析為一個(gè) HttpCookie 對(duì)象的列表。

String cookiesHeader = con.getHeaderField("Set-Cookie");
List<HttpCookie> cookies = HttpCookie.parse(cookiesHeader);

接下來,我們將把cookie添加到cookieStore。

cookies.forEach(cookie -> cookieManager.getCookieStore().add(null, 
cookie));

讓我們檢查一下是否有一個(gè)叫做 username 的 cookie,如果沒有,我們將把它添加到cookieStore,其值為 "javanorth"。

Optional<HttpCookie> usernameCookie = cookies.stream().findAny().filter(cookie -> cookie.getName().equals("username"));
if (usernameCookie == null) {
cookieManager.getCookieStore().add(null, new HttpCookie("username", "javanorth"));
}

最后,為了在請(qǐng)求中加入 cookie,我們需要在關(guān)閉和重新打開連接后設(shè)置 Cookie 頭。

con.disconnect();
con = (HttpURLConnection) url.openConnection();

con.setRequestProperty("Cookie", StringUtils.join(cookieManager.getCookieStore().getCookies(), ";"));

處理重定向

我們可以通過使用參數(shù)為 true 或 false 的 setInstanceFollowRedirects() 方法,為一個(gè)特定的連接啟用或禁用自動(dòng)跟蹤重定向。

con.setInstanceFollowRedirects(false);

也可以啟用或禁用所有連接的自動(dòng)重定向。

HttpUrlConnection.setFollowRedirects(false);

默認(rèn)情況下,該行為是啟用的。

當(dāng)一個(gè)請(qǐng)求返回狀態(tài)代碼 301 或 302,表示重定向時(shí),我們可以檢索位置頭并創(chuàng)建一個(gè)新的請(qǐng)求到新的URL。

if (status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_MOVED_PERM) {
String location = con.getHeaderField("Location");
URL newUrl = new URL(location);
con = (HttpURLConnection) newUrl.openConnection();
}

讀取響應(yīng)

讀取請(qǐng)求的響應(yīng)可以通過解析 HttpUrlConnection 實(shí)例的 InputStream 來完成。

為了執(zhí)行請(qǐng)求,我們可以使用 getResponseCode()、connect()、getInputStream() 或 getOutputStream() 方法。

int status = con.getResponseCode();

最后,讓我們讀一下請(qǐng)求的響應(yīng),并把它放在一個(gè)內(nèi)容字符串中。

BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();

要關(guān)閉連接,我們可以使用 disconnect() 方法。

con.disconnect();

在失敗的請(qǐng)求中讀取響應(yīng)

如果請(qǐng)求失敗了,我們從 HttpUrlConnection 實(shí)例的 InputStream 讀取是讀取不到數(shù)據(jù)的。我們可以從 HttpUrlConnection.getErrorStream() 提供的流讀取。

我們可以通過比較 HTTP 狀態(tài)碼來決定使用哪個(gè) InputStream。

int status = con.getResponseCode();

Reader streamReader = null;

if (status > 299) {
streamReader = new InputStreamReader(con.getErrorStream());
} else {
streamReader = new InputStreamReader(con.getInputStream());
}

最后,我們可以用與上一節(jié)相同的方式讀取 streamReader。

總結(jié)在這篇文章中,我們展示了如何使用 HttpUrlConnection 類來執(zhí)行HTTP請(qǐng)求。

責(zé)任編輯:武曉燕 來源: Java技術(shù)指北
相關(guān)推薦

2023-07-31 08:26:09

2021-09-28 13:42:55

Chrome Devwebsocket網(wǎng)絡(luò)協(xié)議

2021-01-18 05:13:04

TomcatHttp

2024-05-28 10:14:31

JavaScrip模板引擎

2021-05-27 05:37:10

HTTP請(qǐng)求頭瀏覽器

2021-06-09 07:55:19

NodeEventEmitte驅(qū)動(dòng)

2020-05-13 14:35:47

HashMap面試官Java

2021-05-19 08:17:35

秒殺場(chǎng)景高并發(fā)

2022-01-10 11:04:41

單鏈表面試編程

2022-08-18 20:02:04

JSLRU緩存

2020-06-22 07:47:46

提交面試官訂單

2017-03-16 15:27:10

面試官測(cè)試技術(shù)

2019-12-02 10:51:11

Redis存儲(chǔ)系統(tǒng)

2024-04-09 08:39:16

本地緩存開發(fā)線程安全

2021-05-12 08:20:53

開發(fā)

2020-04-20 08:35:48

HTTP HTTPS網(wǎng)絡(luò)協(xié)議

2021-11-02 09:05:25

Redis

2025-03-07 00:00:10

2024-02-20 14:10:55

系統(tǒng)緩存冗余

2024-08-22 10:39:50

@Async注解代理
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)