更新時(shí)間:2022-05-13 10:10:56 來源:動(dòng)力節(jié)點(diǎn) 瀏覽3667次
從 Java 1.1 開始,JDK 提供的核心庫(kù)中就有一個(gè) HTTP 客戶端。Java 11 添加了一個(gè)新的客戶端。如果您對(duì)向項(xiàng)目中添加額外的依賴項(xiàng)敏感,其中之一可能是一個(gè)不錯(cuò)的選擇。
Java 1.1 HttpURL連接
以下是您將如何使用它來發(fā)出GET請(qǐng)求以獲取 APOD 數(shù)據(jù):
// Create a neat value object to hold the URL
URL url = new URL("https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY");
// Open a connection(?) on the URL(??) and cast the response(???)
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Now it's "open", we can set the request method, headers etc.
connection.setRequestProperty("accept", "application/json");
// This line makes the request
InputStream responseStream = connection.getInputStream();
// Manually converting the response body InputStream to APOD using Jackson
ObjectMapper mapper = new ObjectMapper();
APOD apod = mapper.readValue(responseStream, APOD.class);
// Finally we have the response
System.out.println(apod.title);
Java 11 HttpClient
HttpClient 接受BodyHandler可以將 HTTP 響應(yīng)轉(zhuǎn)換為您選擇的類。有一些內(nèi)置的處理程序:String,byte[]用于二進(jìn)制數(shù)據(jù),Stream按行分割,還有一些其他的。BodyHandler您也可以定義自己的,這可能會(huì)有所幫助,因?yàn)闆]有用于解析 JSON的內(nèi)置函數(shù)。我已經(jīng)按照 Java Docs 中的示例基于 Jackson 編寫了一個(gè)(此處)。它為APOD 類返回一個(gè),因此我們?cè)谛枰Y(jié)果時(shí)調(diào)用。Supplier.get()
這是一個(gè)同步請(qǐng)求:
// create a client
var client = HttpClient.newHttpClient();
// create a request
var request = HttpRequest.newBuilder(
URI.create("https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY"))
.header("accept", "application/json")
.build();
// use the client to send the request
var response = client.send(request, new JsonBodyHandler<>(APOD.class));
// the response:
System.out.println(response.body().get().title);
對(duì)于異步請(qǐng)求,clientandrequest以相同的方式進(jìn)行,然后調(diào)用.sendAsync而不是.send:
// use the client to send the request
var responseFuture = client.sendAsync(request, new JsonBodyHandler<>(APOD.class));
// We can do other things here while the request is in-flight
// This blocks until the request is complete
var response = responseFuture.get();
// the response:
System.out.println(response.body().get().title);
如果內(nèi)置客戶端不適合您,請(qǐng)不要擔(dān)心!您可以將許多庫(kù)引入您的項(xiàng)目中,它們可以完成這項(xiàng)工作。
Apache HttpClient
Apache Software Foundation 的 HTTP客戶端已經(jīng)存在了很長(zhǎng)時(shí)間。它們被廣泛使用,并且是許多高級(jí)庫(kù)的基礎(chǔ)。歷史有點(diǎn)混亂。舊的Commons HttpClient不再開發(fā),新版本(也稱為 HttpClient)在HttpComponents項(xiàng)目下。5.0 版于 2020 年初發(fā)布,增加了 HTTP/2 支持。該庫(kù)還支持同步和異步請(qǐng)求。
總體而言,API 相當(dāng)?shù)图?jí) - 您需要自己實(shí)現(xiàn)很多。以下代碼調(diào)用 NASA API。
ObjectMapper mapper = new ObjectMapper();
try (CloseableHttpClient client = HttpClients.createDefault()) {
HttpGet request = new HttpGet("https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY");
APOD response = client.execute(request, httpResponse ->
mapper.readValue(httpResponse.getEntity().getContent(), APOD.class));
System.out.println(response.title);
}
OkHttp
OkHttp是Square的 HTTP 客戶端,具有許多有用的內(nèi)置功能,例如自動(dòng)處理 GZIP、響應(yīng)緩存和重試或在網(wǎng)絡(luò)錯(cuò)誤的情況下回退到其他主機(jī)以及 HTTP/2 和 WebSocket 支持。盡管沒有內(nèi)置的 JSON 響應(yīng)解析,但 API 是干凈的,所以我再次添加了代碼來解析 JSON 與 Jackson:
ObjectMapper mapper = new ObjectMapper();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY")
.build(); // defaults to GET
Response response = client.newCall(request).execute();
APOD apod = mapper.readValue(response.body().byteStream(), APOD.class);
System.out.println(apod.title);
這很好,但是當(dāng)您在頂部添加 Retrofit 時(shí),OkHttp 的真正威力就很明顯了。
Retrofit
Retrofit是 Square 的另一個(gè)庫(kù),建立在 OkHttp 之上。除了 OkHttp 的所有低級(jí)特性外,它還添加了一種構(gòu)建 Java 類的方法,這些類抽象了 HTTP 細(xì)節(jié)并提供了一個(gè)很好的 Java 友好 API。
首先,我們需要?jiǎng)?chuàng)建一個(gè)接口來聲明我們想要針對(duì) APOD API 調(diào)用的方法,并使用注釋定義這些方法如何對(duì)應(yīng)于 HTTP 請(qǐng)求:
public interface APODClient {
@GET("/planetary/apod")
@Headers("accept: application/json")
CompletableFuture<APOD> getApod(@Query("api_key") String apiKey);
}
返回類型CompletableFuture<APOD>使其成為異步客戶端。Square 提供其他適配器,或者您可以編寫自己的適配器。
在聲明接口之后,我們要求 Retrofit 創(chuàng)建一個(gè)實(shí)現(xiàn),我們可以使用它來針對(duì)給定的基本 URL 發(fā)出請(qǐng)求。能夠切換基本 URL 對(duì)集成測(cè)試也很有幫助。要生成客戶端,代碼如下所示:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.nasa.gov")
.addConverterFactory(JacksonConverterFactory.create())
.build();
APODClient apodClient = retrofit.create(APODClient.class);
CompletableFuture<APOD> response = apodClient.getApod("DEMO_KEY");
// do other stuff here while the request is in-flight
APOD apod = response.get();
System.out.println(apod.title);
API 認(rèn)證
如果我們的接口中有多個(gè)方法都需要一個(gè) API 密鑰,則可以通過HttpInterceptor在 base 中添加一個(gè)來配置它OkHttpClient。可以將自定義客戶端添加到Retrofit.Builder. 創(chuàng)建自定義客戶端所需的代碼是:
private OkHttpClient clientWithApiKey(String apiKey) {
return new OkHttpClient.Builder()
.addInterceptor(chain -> {
Request originalRequest = chain.request();
HttpUrl newUrl = originalRequest.url().newBuilder()
.addQueryParameter("api_key", apiKey).build();
Request request = originalRequest.newBuilder().url(newUrl).build();
return chain.proceed(request);
}).build();
}
構(gòu)建類來表示遠(yuǎn)程 API 是一個(gè)很好的抽象,可以很好地與依賴注入配合使用,并且讓 Retrofit 基于可定制的 OkHttp 客戶端為您創(chuàng)建它們非常棒。
如果以上都不是您想要的,請(qǐng)查看以下建議:
REST Assured - 專為測(cè)試您的 REST 服務(wù)而設(shè)計(jì)的 HTTP 客戶端。提供用于發(fā)出請(qǐng)求的流暢界面和用于對(duì)響應(yīng)進(jìn)行斷言的有用方法。
cvurl - Java 11 HttpClient 的包裝器,它使您在發(fā)出復(fù)雜請(qǐng)求時(shí)可能會(huì)遇到一些尖銳的邊緣。
Feign - 與 Retrofit 類似,F(xiàn)eign 可以從帶注釋的接口構(gòu)建類。Feign 非常靈活,可以通過多種選項(xiàng)來發(fā)出和讀取請(qǐng)求、指標(biāo)、重試等等。
Spring RestTemplate(同步)和WebClient(異步)客戶端 - 如果您在項(xiàng)目中的其他所有內(nèi)容中都使用過 Spring,那么堅(jiān)持使用該生態(tài)系統(tǒng)可能是一個(gè)好主意。Baeldung 有一篇文章比較它們。
MicroProfile Rest Client - 另一個(gè)處于“從帶注釋的接口構(gòu)建類”模式的客戶端,這個(gè)很有趣,因?yàn)槟部梢灾赜孟嗤慕涌趤韯?chuàng)建 Web 服務(wù)器,并確保客戶端和服務(wù)器匹配。如果您正在為該服務(wù)構(gòu)建服務(wù)和客戶端,那么它可能適合您。
相關(guān)閱讀
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)
初級(jí) 202925
初級(jí) 203221
初級(jí) 202629
初級(jí) 203743