使用 Java 將 cURL 請求轉換為 HTTP 請求
1. 簡介
當我們使用 API 時,我們通常會先使用 cURL 來測試我們的請求。 cURL 是一個命令列工具,可以幫助我們輕鬆地發送 HTTP 請求。在本教程中,我們將介紹幾種在 Java 中將 cURL 轉換為 HTTP 請求的方法。
2.了解 cURL 指令
讓我們從一個典型的 cURL 指令開始:
curl -X POST "http://example.com/api" \
-H "Content-Type: application/json" \
-d '{"key1":"value1", "key2":"value2"}'
此命令向 URL http://example.com/api
發送POST
請求,具有以下特徵:
-
-X POST
:指定HTTP方法,使用POST向伺服器傳送數據 -
-H “Content-Type: application/json”
:新增標頭,表示請求主體為 JSON 格式 - –
d '{“key1″:”value1”, “key2″:”value2”}'
:將有效負載(請求正文)作為包含兩個鍵值對的 JSON 字串提供
雖然 cURL 非常適合測試端點,但將這些命令轉換為 Java 程式碼可以使我們的 API 呼叫可重複使用、可測試,並且更好地處理實際專案中的錯誤。我們可以使用 Java 中提供的幾種不同的程式庫和工具來實現這一點。
3. Java內建的HttpURLConnection
在 Java 中發出 HTTP 請求的最簡單方法之一是使用 Java 標準庫中內建的HttpURLConnection
類別。這種方法很簡單,不需要額外的依賴。
以下是如何使用HttpURLConnection
將早期的 cURL 指令轉換為 Java HTTP 請求的範例:
String sendPostWithHttpURLConnection(String targetUrl) {
StringBuilder response = new StringBuilder();
try {
URL url = new URL(targetUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json; utf-8");
conn.setRequestProperty("Accept", "application/json");
conn.setDoOutput(true);
String jsonInputString = "{\"key1\":\"value1\", \"key2\":\"value2\"}";
try (OutputStream os = conn.getOutputStream()) {
byte[] input = jsonInputString.getBytes("utf-8");
os.write(input, 0, input.length);
}
int code = conn.getResponseCode();
logger.info("Response Code: " + code);
try (BufferedReader br = new BufferedReader(
new InputStreamReader(conn.getInputStream(), "utf-8"))) {
String responseLine;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
}
} catch (Exception e) {
// handle exception
}
return response.toString();
}
我們首先使用URL
類別來設定連線以建立一個 URL 對象,然後使用HttpURLConnection
開啟連線。接下來,我們將請求方法設為POST
,並使用setRequestProperty()
新增標頭,以指定我們的請求正文是 JSON,並且我們期望 JSON 回應。
一旦請求被發送,我們從伺服器取得回應代碼並使用BufferedReader
讀取回應,將每一行附加到StringBuilder
。
下面是一個簡單的測試案例,當發送有效的 POST 請求時,它會斷言非空響應:
String targetUrl = mockWebServer.url("/api").toString();
String response = CurlToHttpRequest.sendPostWithHttpURLConnection(targetUrl);
assertNotNull(response);
assertFalse(response.isEmpty());
assertEquals("{\"message\": \"Success\"}", response);
4. Apache HttpClient
Apache HttpClient 是一個用於發出 HTTP 請求的強大且受歡迎的函式庫。它比內建的HttpURLConnection
提供了更多的控制和靈活性。
首先,我們將其依賴項新增到我們的pom.xml
中:
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.4.2</version>
</dependency>
以下是我們使用 Apache HttpClient 轉換 cURL 請求的方法:
String sendPostRequestUsingApacheHttpClient(String targetUrl) {
String result = "";
try (CloseableHttpClient client = HttpClients.createDefault()) {
HttpPost httpPost = new HttpPost(targetUrl);
httpPost.setHeader("Content-Type", "application/json");
String jsonInput = "{\"key1\":\"value1\", \"key2\":\"value2\"}";
StringEntity entity = new StringEntity(jsonInput);
httpPost.setEntity(entity);
try (CloseableHttpResponse response = client.execute(httpPost)) {
result = EntityUtils.toString(response.getEntity());
logger.info("Response Code: " + response.getStatusLine().getStatusCode());
}
} catch (Exception e) {
// handle exception
}
return result;
}
在這個範例中,我們建立一個CloseableHttpClient
實例並使用它向目標 URL 執行POST
請求。我們設定Content-Type
標頭來表明我們正在發送 JSON 資料。 JSON 有效負載包裝在StringEntity
中並附加到HttpPost
請求。執行請求後,我們將回應實體轉換為字串。
Apache HttpClient 使我們能夠自訂 HTTP 通訊的許多方面。我們可以輕鬆調整連線逾時,管理連線池,新增用於日誌記錄或驗證的攔截器,以及處理重試或重新導向。
以下是一個範例,展示如何自訂 Apache HttpClient 來設定連線逾時並新增一個用於記錄請求詳細資料的攔截器:
String sendPostRequestUsingApacheHttpClientWithCustomConfig(String targetUrl) {
String result = "";
// Create custom configuration for connection and response timeouts.
RequestConfig config = RequestConfig.custom()
.setConnectTimeout(Timeout.ofSeconds(10))
.setResponseTimeout(Timeout.ofSeconds(15))
.build();
// Create a custom HttpClient with a logging interceptor.
CloseableHttpClient client = HttpClientBuilder.create()
.setDefaultRequestConfig(config)
.addRequestInterceptorFirst(new HttpRequestInterceptor() {
@Override
public void process(HttpRequest request, EntityDetails entity, HttpContext context) {
logger.info("Request URI: " + request.getRequestUri());
logger.info("Request Headers: " + request.getHeaders());
}
})
.build();
try {
HttpPost httpPost = new HttpPost(targetUrl);
httpPost.setHeader("Content-Type", "application/json");
String jsonInput = "{\"key1\":\"value1\", \"key2\":\"value2\"}";
StringEntity entity = new StringEntity(jsonInput);
httpPost.setEntity(entity);
try (CloseableHttpResponse response = client.execute(httpPost)) {
result = EntityUtils.toString(response.getEntity());
logger.info("Response Code: " + response.getCode());
}
} catch (Exception e) {
// Handle exception appropriately
} finally {
// close the client and handle exception
}
return result;
}
在這個自訂方法中,我們首先建立一個RequestConfig
,將連線逾時設為10
秒,將回應逾時設為15
秒。
此外,我們新增了一個請求攔截器,它在執行請求之前記錄請求 URI 和標頭。該攔截器提供了有關請求細節的寶貴見解,這對於調試或監控很有用。
5. OkHttp
OkHttp 是 Square 推出的一款現代 HTTP 用戶端,以易用性和卓越效能而聞名。它支援HTTP/2並廣泛應用於Android和Java應用程式。
讓我們將依賴項新增到我們的pom.xml
中:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
以下展示如何使用 OkHttp 將 cURL 請求轉換為 HTTP 請求:
String sendPostRequestUsingOkHttp(String targetUrl) {
OkHttpClient client = new OkHttpClient();
MediaType JSON = MediaType.get("application/json; charset=utf-8");
String jsonInput = "{\"key1\":\"value1\", \"key2\":\"value2\"}";
RequestBody body = RequestBody.create(jsonInput, JSON);
Request request = new Request.Builder()
.url(targetUrl)
.post(body)
.build();
String result = "";
try (Response response = client.newCall(request).execute()) {
logger.info("Response Code: " + response.code());
result = response.body().string();
} catch (Exception e) {
// handle exception
}
return result;
}
在此程式碼中,我們定義一個RequestBody
來儲存 JSON 負載並指定其內容類型。接下來,我們使用Request.Builder()
來設定目標 URL、HTTP 方法(POST)、請求正文和標頭。
最後,我們使用client.newCall(request).execute()
執行請求,處理可能發生的任何異常。
6. Spring 的 WebClient
此外,當使用Spring框架時, WebClient
是簡化HTTP請求的高階用戶端。它是一個現代的、非阻塞的 HTTP 用戶端,也是在 Spring 應用程式中發出 HTTP 請求的建議方式。
我們將 cURL 範例轉換為使用WebClient
:
String sendPostRequestUsingWebClient(String targetUrl) {
WebClient webClient = WebClient.builder()
.baseUrl(targetUrl)
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.build();
String jsonInput = "{\"key1\":\"value1\", \"key2\":\"value2\"}";
return webClient.post()
.bodyValue(jsonInput)
.retrieve()
.bodyToMono(String.class)
.doOnNext(response -> logger.info("Response received from WebClient: " + response))
.block();
}
在此範例中,我們建立一個具有目標URL
的WebClient
實例,並將Content-Type
標頭設定為application/json
。然後,我們使用bodyValue(jsonInput)
來附加 JSON 有效負載。此外,我們新增了block()
以確保方法同步執行並回傳回應。
或者,如果我們在非同步或反應式應用程式中工作,我們可以刪除block()
方法並傳回Mono<String>
而不是String
。
7. 結論
在本文中,我們探討如何使用各種函式庫和工具將簡單的 cURL 指令轉換為 Java 程式碼。 HttpURLConnection
非常適合我們想要避免外部依賴的簡單用例。 Apache HttpClient 非常適合需要對 HTTP 請求進行細粒度控制的應用程式。
此外,OkHttp 是一個現代 HTTP 用戶端,以其效能而聞名,非常適合微服務或 Android 開發。 Spring WebClient 最適合反應式應用程序,特別是在 Spring 生態系統中。
與往常一樣,原始碼可 在 GitHub 上取得。