

در این مقاله نحوهٔ ارسال درخواستهای POST در زبان Java با دو کتابخانهٔ محبوب — Apache HttpClient (نسخهٔ 5) و OKHttp (نسخهٔ 4) — را با نگاه به کاربردهای وب اسکریپینگ توضیح میدهیم. مخاطب این راهنما توسعهدهندهٔ Python در سطح متوسط است؛ بنابراین ضمن تشریح جزئیات Java، معادلهای سادهٔ Python با requests نیز نشان داده میشود تا درک مقایسهای آسانتر شود. در پایان یاد میگیرید چگونه JSON و فرمداده ارسال کنید، تفاوت اجرای همزمان/غیرهمزمان را بفهمید و نکات عملی برای پایداری، امنیت و جلوگیری از بلاک شدن در اسکریپ را بهکار ببرید.
ایدهٔ کلی: ارسال payload از نوع JSON به یک endpoint معمولی در API. در HttpClient نسخهٔ 5 مثال زیر از حالت غیرهمزمان (CloseableHttpAsyncClient) استفاده میکند که خروجی آن یک Future<SimpleHttpResponse> است.
مراحل:
مثال کامل:
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
import org.apache.hc.core5.http.ContentType;
import java.util.concurrent.Future;
public class JsonPostRequest {
public static void main(String[] args) throws Exception {
String requestUrl = "https://httpbin.org/post";
String jsonData = "{\"key\": \"value\"}"; // payload JSON
CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
client.start();
try {
SimpleHttpRequest request = SimpleRequestBuilder.post(requestUrl)
.setBody(jsonData, ContentType.APPLICATION_JSON)
.build();
Future future = client.execute(request, null);
SimpleHttpResponse response = future.get();
System.out.println("Response body: " + response.getBodyText());
} finally {
client.close();
}
}
}
توضیح کد:
نکات عملی و هشدارها:
ایدهٔ کلی: در OKHttp نمونهٔ عادی (همزمان) رایج است اما میتوان درخواستها را به صورت غیرهمزمان هم فرستاد. ابتدا کلاینت را میسازیم، سپس MediaType و RequestBody را ایجاد کرده و با Request.Builder آن را ارسال میکنیم.
import java.util.concurrent.TimeUnit;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class JsonPostOkHttp {
public static void main(String[] args) throws Exception {
String requestUrl = "https://httpbin.org/post";
String jsonData = "{\"key\": \"value\"}";
OkHttpClient client = new OkHttpClient.Builder()
.readTimeout(30, TimeUnit.SECONDS)
.build();
MediaType contentType = MediaType.get("application/json");
RequestBody body = RequestBody.create(jsonData, contentType);
Request request = new Request.Builder()
.url(requestUrl)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
System.out.println("Response body: " + response.body().string());
}
}
}
توضیح کد:
معادل سریع در Python با requests (برای مقایسه):
import requests
resp = requests.post("https://httpbin.org/post", json={"key": "value"}, timeout=30)
print(resp.text)
فرمت فرمدرخواستها معمولا application/x-www-form-urlencoded است. در هر دو کتابخانه باید Content-Type مناسب را ست کنیم و بدنه را به صورت رشتهٔ کدشده یا با استفاده از کلاسهای helper بسازیم.
برای HttpClient دوباره از setBody استفاده میکنیم ولی با ContentType.APPLICATION_FORM_URLENCODED:
// imports omitted for brevity (see previous examples)
public class FormDataPostRequest {
public static void main(String[] args) throws Exception {
String requestUrl = "https://httpbin.org/post";
String formData = "key1=value1&key2=value2"; // URL-encoded string
CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
client.start();
try {
SimpleHttpRequest request = SimpleRequestBuilder.post(requestUrl)
.setBody(formData, ContentType.APPLICATION_FORM_URLENCODED)
.build();
Future future = client.execute(request, null);
SimpleHttpResponse response = future.get();
System.out.println("Response body: " + response.getBodyText());
} finally {
client.close();
}
}
}
نکات:
در OKHttp محتوای فرم را با تعیین MediaType برابر با application/x-www-form-urlencoded میسازیم:
// imports omitted for brevity
public class FormDataPostOkHttp {
public static void main(String[] args) throws Exception {
String requestUrl = "https://httpbin.org/post";
String formData = "key1=value1&key2=value2";
OkHttpClient client = new OkHttpClient.Builder()
.readTimeout(30, TimeUnit.SECONDS)
.build();
MediaType contentType = MediaType.get("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(formData, contentType);
Request request = new Request.Builder()
.url(requestUrl)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
System.out.println("Response body: " + response.body().string());
}
}
}
مزایا و معایب کوتاه:
اگر در اکوسیستم Python هستید و با سرویسهای نوشتهشده در Java تعامل دارید، معمولاً کافی است از requests برای POST JSON یا فرم استفاده کنید. اما برای تست یا مقایسه رفتار، دانستن تفاوتهای پیشفرضی مانند headerهای اضافهشده، اتصالهای keep-alive و مدیریت زمانبندی در کتابخانههای Java مفید است.
# مثال معادل ارسال فرم در Python
import requests
resp = requests.post("https://httpbin.org/post",
data={"key1": "value1", "key2": "value2"},
headers={"User-Agent": "my-scraper/1.0"},
timeout=30)
print(resp.text)
در این راهنما شیوههای مرسوم ارسال درخواستهای POST با Apache HttpClient و OKHttp را برای JSON و فرمداده توضیح دادیم و نکات عملی برای استفاده در وب اسکریپینگ را مرور کردیم. انتخاب بین این دو بستگی به نیاز شما به کنترل ریز، همزمانی و سادگی API دارد. در نهایت همیشه timeout، مدیریت منابع (بستن کلاینت/پاسخ)، و سیاستهای retry را در پیادهسازی اسکریپهایتان در نظر بگیرید.