自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

面試官:請用Java實現(xiàn)一個HTTP請求

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

大家好,我是指北君。

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

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

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

HttpUrlConnection

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

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

創(chuàng)建一個請求

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

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

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

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

添加請求參數(shù)

如果我們想向一個請求添加參數(shù),我們必須將 doOutput 屬性設(shè)置為 true,然后向 HttpUrlConnection 實例的OutputStream 寫一個類似 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)換,我們編寫了一個名為ParameterStringBuilder的實用類,其中包含一個靜態(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è)置請求頭信息

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

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

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

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

配置超時

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

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

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

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

處理Cookie

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

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

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

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

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

讓我們檢查一下是否有一個叫做 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"));
}

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

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

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

處理重定向

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

con.setInstanceFollowRedirects(false);

也可以啟用或禁用所有連接的自動重定向。

HttpUrlConnection.setFollowRedirects(false);

默認情況下,該行為是啟用的。

當一個請求返回狀態(tài)代碼 301 或 302,表示重定向時,我們可以檢索位置頭并創(chuà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();
}

讀取響應

讀取請求的響應可以通過解析 HttpUrlConnection 實例的 InputStream 來完成。

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

int status = con.getResponseCode();

最后,讓我們讀一下請求的響應,并把它放在一個內(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();

在失敗的請求中讀取響應

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

我們可以通過比較 HTTP 狀態(tài)碼來決定使用哪個 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請求。

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

2023-07-31 08:26:09

2021-09-28 13:42:55

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

2024-05-28 10:14:31

JavaScrip模板引擎

2021-01-18 05:13:04

TomcatHttp

2021-05-27 05:37:10

HTTP請求頭瀏覽器

2021-06-09 07:55:19

NodeEventEmitte驅(qū)動

2021-05-19 08:17:35

秒殺場景高并發(fā)

2020-05-13 14:35:47

HashMap面試官Java

2022-01-10 11:04:41

單鏈表面試編程

2020-06-22 07:47:46

提交面試官訂單

2022-08-18 20:02:04

JSLRU緩存

2019-12-02 10:51:11

Redis存儲系統(tǒng)

2024-04-09 08:39:16

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

2017-03-16 15:27:10

面試官測試技術(shù)

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

2024-08-22 10:39:50

@Async注解代理

2024-03-05 10:33:39

AOPSpring編程

2025-03-07 00:00:10

點贊
收藏

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