Java ekosisteminde HTTP istemcileri ve proxy yapılandırması, kurumsal uygulamalardan web kazıma projelerine kadar geniş bir kullanım alanına sahiptir. Bu rehber, modern Java HTTP istemcilerinde proxy kullanımını derinlemesine ele alır; kimlik doğrulama, bağlantı havuzu yönetimi ve üretim düzeyinde hata işleme stratejilerini kapsar.
Java 11+ HttpClient ile Proxy Kullanımı
Java 11 ile tanıtılan modern HttpClient API'si, HTTP/2 desteği ve akıcı API tasarımıyla öne çıkar. Proxy yapılandırması için ProxySelector ve kimlik doğrulama için Authenticator sınıflarını kullanır.
Temel Proxy Yapılandırması
En basit haliyle, bir HTTP proxy üzerinden istek göndermek için ProxySelector.of() metodunu kullanabilirsiniz:
import java.net.InetSocketAddress;
import java.net.ProxySelector;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
public class JavaHttpClientProxyExample {
public static void main(String[] args) throws Exception {
// Proxy adresi: ProxyHat gateway
var proxyAddress = new InetSocketAddress("gate.proxyhat.com", 8080);
// HttpClient'ı proxy ile yapılandır
var client = HttpClient.newBuilder()
.proxy(ProxySelector.of(proxyAddress))
.connectTimeout(Duration.ofSeconds(30))
.followRedirects(HttpClient.Redirect.NORMAL)
.build();
// Hedef URL'ye istek gönder
var request = HttpRequest.newBuilder()
.uri(URI.create("https://httpbin.org/ip"))
.timeout(Duration.ofSeconds(60))
.GET()
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status: " + response.statusCode());
System.out.println("Body: " + response.body());
}
}
Bu örnekte, tüm istekler belirtilen proxy üzerinden yönlendirilir. Ancak, gerçek dünya senaryolarında genellikle kimlik doğrulama gereklidir.
Kimlik Doğrulamalı Proxy Yapılandırması
ProxyHat gibi ücretli proxy servisleri, kullanıcı adı ve şifre gerektirir. Java HttpClient'da bu, Authenticator sınıfı ile sağlanır:
import java.net.Authenticator;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.ProxySelector;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
public class JavaHttpClientAuthProxy {
private static final String PROXY_HOST = "gate.proxyhat.com";
private static final int PROXY_PORT = 8080;
private static final String USERNAME = "user-country-US"; // Ülke hedefleme
private static final String PASSWORD = "your_password";
public static void main(String[] args) throws Exception {
var proxyAddress = new InetSocketAddress(PROXY_HOST, PROXY_PORT);
// Kimlik doğrulama ayarla
var authenticator = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
// Sadece proxy kimlik doğrulaması için
if (getRequestorType() == RequestorType.PROXY) {
return new PasswordAuthentication(USERNAME, PASSWORD.toCharArray());
}
return null;
}
};
var client = HttpClient.newBuilder()
.proxy(ProxySelector.of(proxyAddress))
.authenticator(authenticator)
.connectTimeout(Duration.ofSeconds(30))
.build();
var request = HttpRequest.newBuilder()
.uri(URI.create("https://httpbin.org/ip"))
.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)")
.GET()
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
Authenticator sınıfı, hem proxy hem de hedef sunucu kimlik doğrulaması için kullanılabilir. getRequestorType() kontrolü, yalnızca proxy kimlik doğrulaması yapılmasını sağlar.
OkHttp ile Proxy Kullanımı
OkHttp, Square tarafından geliştirilen popüler bir HTTP istemcisidir. Android ve sunucu tarafı uygulamalarda yaygın olarak kullanılır. Bağlantı havuzu, yeniden deneme mekanizmaları ve modern TLS desteği sunar.
Temel OkHttp Proxy Yapılandırması
OkHttp'de proxy, OkHttpClient.Builder üzerinden yapılandırılır:
import java.net.InetSocketAddress;
import java.net.Proxy;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.time.Duration;
public class OkHttpProxyExample {
private static final String PROXY_HOST = "gate.proxyhat.com";
private static final int PROXY_PORT = 8080;
public static void main(String[] args) throws Exception {
// HTTP proxy tanımla
var proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_HOST, PROXY_PORT));
// OkHttpClient yapılandır
var client = new OkHttpClient.Builder()
.proxy(proxy)
.connectTimeout(Duration.ofSeconds(30))
.readTimeout(Duration.ofSeconds(60))
.writeTimeout(Duration.ofSeconds(60))
.build();
var request = new Request.Builder()
.url("https://httpbin.org/ip")
.header("User-Agent", "Mozilla/5.0")
.build();
try (var response = client.newCall(request).execute()) {
System.out.println("Status: " + response.code());
System.out.println("Body: " + response.body().string());
}
}
}
Kimlik Doğrulamalı OkHttp Proxy
OkHttp'de proxy kimlik doğrulaması için Authenticator arabirimi uygulanır:
import java.net.InetSocketAddress;
import java.net.Proxy;
import okhttp3.Authenticator;
import okhttp3.Credentials;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.Route;
import java.time.Duration;
public class OkHttpAuthProxy {
private static final String PROXY_HOST = "gate.proxyhat.com";
private static final int PROXY_PORT = 8080;
private static final String USERNAME = "user-country-DE-city-berlin"; // Şehir hedefleme
private static final String PASSWORD = "your_password";
public static void main(String[] args) throws Exception {
var proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_HOST, PROXY_PORT));
// Proxy kimlik doğrulama
var proxyAuthenticator = new Authenticator() {
@Override
public Request authenticate(Route route, Response response) {
// Önceki deneme başarısız olduysa, null döndür (yeniden deneme yapma)
if (response.responseCount() >= 3) {
return null;
}
String credential = Credentials.basic(USERNAME, PASSWORD);
return response.request().newBuilder()
.header("Proxy-Authorization", credential)
.build();
}
};
var client = new OkHttpClient.Builder()
.proxy(proxy)
.proxyAuthenticator(proxyAuthenticator)
.connectTimeout(Duration.ofSeconds(30))
.readTimeout(Duration.ofSeconds(60))
.retryOnConnectionFailure(true)
.build();
var request = new Request.Builder()
.url("https://httpbin.org/headers")
.build();
try (var response = client.newCall(request).execute()) {
System.out.println(response.body().string());
}
}
}
response.responseCount() kontrolü, sonsuz kimlik doğrulama döngülerini önler. Yanlış kimlik bilgileri durumunda 3 deneme sonrasında vazgeçer.
Jsoup ile Proxy Destekli HTML Ayrıştırma
Jsoup, HTML ayrıştırma ve işleme için tasarlanmış bir kütüphanedir. Web kazıma işlemlerinde yaygın olarak kullanılır. Jsoup, kendi HTTP istemcisine sahiptir ancak proxy desteği sınırlıdır. Üretim düzeyinde uygulamalarda OkHttp veya Apache HttpClient ile birlikte kullanılması önerilir.
Yerel Jsoup Proxy Desteği
Jsoup'un Jsoup.connect() metodu basit proxy yapılandırmasını destekler:
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.net.InetSocketAddress;
import java.net.Proxy;
public class JsoupProxyExample {
private static final String PROXY_HOST = "gate.proxyhat.com";
private static final int PROXY_PORT = 8080;
public static void main(String[] args) throws Exception {
var proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_HOST, PROXY_PORT));
// Temel proxy ile bağlantı
Document doc = Jsoup.connect("https://example.com")
.proxy(proxy)
.userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64)")
.timeout(30000)
.get();
System.out.println("Title: " + doc.title());
// Sayfadaki tüm linkleri çek
doc.select("a[href]").forEach(link -> {
System.out.println(link.attr("href") + " - " + link.text());
});
}
}
Kimlik Doğrulamalı Jsoup + OkHttp Entegrasyonu
Jsoup'un yerel proxy kimlik doğrulama desteği yoktur. Bu nedenle, kimlik doğrulama gerektiren proxy'lerde OkHttp ile entegrasyon yapılmalıdır:
import okhttp3.Authenticator;
import okhttp3.Credentials;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.Route;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.time.Duration;
public class JsoupOkHttpIntegration {
private static final String PROXY_HOST = "gate.proxyhat.com";
private static final int PROXY_PORT = 8080;
private static final String USERNAME = "user-country-US";
private static final String PASSWORD = "your_password";
public static void main(String[] args) throws Exception {
var proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_HOST, PROXY_PORT));
var proxyAuthenticator = new Authenticator() {
@Override
public Request authenticate(Route route, Response response) {
if (response.responseCount() >= 3) return null;
return response.request().newBuilder()
.header("Proxy-Authorization", Credentials.basic(USERNAME, PASSWORD))
.build();
}
};
var httpClient = new OkHttpClient.Builder()
.proxy(proxy)
.proxyAuthenticator(proxyAuthenticator)
.connectTimeout(Duration.ofSeconds(30))
.build();
String html = fetchHtml(httpClient, "https://example.com");
Document doc = Jsoup.parse(html, "https://example.com");
System.out.println("Title: " + doc.title());
System.out.println("Paragraphs: " + doc.select("p").size());
}
private static String fetchHtml(OkHttpClient client, String url) throws Exception {
var request = new Request.Builder().url(url).build();
try (var response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new RuntimeException("HTTP error: " + response.code());
}
return response.body().string();
}
}
}
Bu yaklaşım, OkHttp'in güçlü bağlantı havuzu ve yeniden deneme mekanizmalarından yararlanırken, Jsoup'un HTML ayrıştırma yeteneklerini kullanmanızı sağlar.
Bağlantı Havuzu, Zaman Aşımı ve Yeniden Deneme Politikaları
Üretim uygulamalarında, bağlantı yönetimi kritik öneme sahiptir. OkHttp, varsayılan olarak bir bağlantı havuzu kullanır, ancak yapılandırma gerekebilir:
import okhttp3.Authenticator;
import okhttp3.ConnectionPool;
import okhttp3.Credentials;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.Route;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
public class ProductionOkHttpClient {
private static final String PROXY_HOST = "gate.proxyhat.com";
private static final int PROXY_PORT = 8080;
private static final String USERNAME = "user-country-US";
private static final String PASSWORD = "your_password";
// Singleton client - uygulama ömrü boyunca yeniden kullan
private static volatile OkHttpClient INSTANCE;
public static OkHttpClient getClient() {
if (INSTANCE == null) {
synchronized (ProductionOkHttpClient.class) {
if (INSTANCE == null) {
INSTANCE = createClient();
}
}
}
return INSTANCE;
}
private static OkHttpClient createClient() {
var proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_HOST, PROXY_PORT));
var proxyAuthenticator = new Authenticator() {
@Override
public Request authenticate(Route route, Response response) {
if (response.responseCount() >= 3) return null;
return response.request().newBuilder()
.header("Proxy-Authorization", Credentials.basic(USERNAME, PASSWORD))
.build();
}
};
// Bağlantı havuzu: max 20 idle bağlantı, 5 dakika keep-alive
var connectionPool = new ConnectionPool(20, 5, TimeUnit.MINUTES);
return new OkHttpClient.Builder()
.proxy(proxy)
.proxyAuthenticator(proxyAuthenticator)
.connectionPool(connectionPool)
.connectTimeout(Duration.ofSeconds(30))
.readTimeout(Duration.ofSeconds(60))
.writeTimeout(Duration.ofSeconds(30))
.retryOnConnectionFailure(true)
.followRedirects(true)
.followSslRedirects(true)
.build();
}
public static void main(String[] args) throws Exception {
var client = getClient();
// Birden fazla istek aynı client ile yapılır
for (int i = 0; i < 10; i++) {
var request = new Request.Builder()
.url("https://httpbin.org/delay/1")
.build();
try (var response = client.newCall(request).execute()) {
System.out.println("Request " + i + ": " + response.code());
}
}
}
}
Yeniden Deneme Stratejileri
OkHttp'in yerel yeniden deneme mekanizması bağlantı hataları için çalışır, ancak HTTP hata kodları için özel bir interceptor gerekebilir:
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
public class RetryInterceptor implements Interceptor {
private final int maxRetries;
private final long retryDelayMs;
public RetryInterceptor(int maxRetries, long retryDelayMs) {
this.maxRetries = maxRetries;
this.retryDelayMs = retryDelayMs;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = null;
IOException lastException = null;
for (int attempt = 0; attempt <= maxRetries; attempt++) {
try {
response = chain.proceed(request);
// 5xx sunucu hatalarında yeniden dene
if (response.isSuccessful() || response.code() < 500) {
return response;
}
// Yanlış response'u kapat
response.close();
} catch (IOException e) {
lastException = e;
}
// Bekle ve tekrar dene
if (attempt < maxRetries) {
try {
Thread.sleep(retryDelayMs * (attempt + 1)); // Exponential backoff
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}
if (lastException != null) {
throw lastException;
}
return response;
}
}
// Kullanım
var client = new OkHttpClient.Builder()
.addInterceptor(new RetryInterceptor(3, 1000))
.connectTimeout(Duration.ofSeconds(30))
.build();
Apache HttpClient ile Proxy (Eski Ekosistemler)
Apache HttpClient, birçok kurumsal projede hala kullanılmaktadır. Klasik API ve asenkron API olmak üzere iki varyantı vardır:
import org.apache.hc.client5.http.auth.AuthScope;
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.io.entity.EntityUtils;
public class ApacheHttpClientProxy {
private static final String PROXY_HOST = "gate.proxyhat.com";
private static final int PROXY_PORT = 8080;
private static final String USERNAME = "user-country-US";
private static final String PASSWORD = "your_password";
public static void main(String[] args) throws Exception {
// Proxy host tanımla
var proxyHost = new HttpHost(PROXY_HOST, PROXY_PORT);
// Kimlik bilgileri sağlayıcısı
var credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(
new AuthScope(proxyHost),
new UsernamePasswordCredentials(USERNAME, PASSWORD.toCharArray())
);
// HttpClient oluştur
try (var httpClient = HttpClients.custom()
.setProxy(proxyHost)
.setDefaultCredentialsProvider(credentialsProvider)
.build()) {
var httpGet = new HttpGet("https://httpbin.org/ip");
httpClient.execute(httpGet, response -> {
String body = EntityUtils.toString(response.getEntity());
System.out.println("Status: " + response.getCode());
System.out.println("Body: " + body);
return null;
});
}
}
}
Apache HttpClient 5.x, modern Java projelerinde Java 11+ HttpClient veya OkHttp tercih edilmesine rağmen, legacy sistemlerde yaygın olarak kullanılmaktadır.
Paralel Kazıma: ExecutorService ile Residential Proxy Havuzu
Yüksek hacimli veri toplama işlemlerinde, residential proxy havuzu üzerinden paralel istekler göndermek verimliliği artırır. Her istek farklı bir IP adresinden gelir, bu da hız sınırlama ve engellemeleri azaltır:
import okhttp3.Authenticator;
import okhttp3.Credentials;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.Route;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class ParallelScraper {
private static final String PROXY_HOST = "gate.proxyhat.com";
private static final int PROXY_PORT = 8080;
private static final String BASE_USERNAME = "user-country-US";
private static final String PASSWORD = "your_password";
private static final AtomicInteger SESSION_COUNTER = new AtomicInteger(0);
// Her thread için ayrı OkHttpClient (sticky session için)
private static OkHttpClient createClientWithSession() {
String sessionUsername = BASE_USERNAME + "-session-" + SESSION_COUNTER.incrementAndGet();
var proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_HOST, PROXY_PORT));
var proxyAuthenticator = new Authenticator() {
@Override
public Request authenticate(Route route, Response response) {
if (response.responseCount() >= 3) return null;
return response.request().newBuilder()
.header("Proxy-Authorization", Credentials.basic(sessionUsername, PASSWORD))
.build();
}
};
return new OkHttpClient.Builder()
.proxy(proxy)
.proxyAuthenticator(proxyAuthenticator)
.connectTimeout(Duration.ofSeconds(30))
.readTimeout(Duration.ofSeconds(60))
.build();
}
public static void main(String[] args) throws Exception {
List<String> urls = List.of(
"https://httpbin.org/ip",
"https://httpbin.org/headers",
"https://httpbin.org/user-agent",
"https://httpbin.org/get",
"https://httpbin.org/delay/1",
"https://httpbin.org/delay/2"
);
int threadCount = 6;
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
// Her URL için bir task oluştur
List<Callable<String>> tasks = urls.stream()
.map(url -> (Callable<String>) () -> fetchUrl(url))
.toList();
// Tüm task'ları paralel çalıştır
List<Future<String>> futures = executor.invokeAll(tasks, 120, TimeUnit.SECONDS);
// Sonuçları topla
for (int i = 0; i < futures.size(); i++) {
try {
String result = futures.get(i).get();
System.out.println("URL " + i + ": " + result.substring(0, Math.min(100, result.length())));
} catch (Exception e) {
System.err.println("URL " + i + " failed: " + e.getMessage());
}
}
executor.shutdown();
}
private static String fetchUrl(String url) {
var client = createClientWithSession();
var request = new Request.Builder().url(url).build();
try (var response = client.newCall(request).execute()) {
return response.body().string();
} catch (Exception e) {
return "Error: " + e.getMessage();
}
}
}
Bu örnekte, her thread için ayrı bir session ID'si kullanılır. ProxyHat'ın sticky session desteği sayesinde, aynı thread içindeki tüm istekler aynı IP adresinden gelir. Bu, oturum tutarlılığı gerektiren senaryolarda (örneğin, çok adımlı formlar) kritik öneme sahiptir.
TLS ve SSL Yapılandırması
Bazı proxy servisleri veya hedef sunucular, standart olmayan TLS sertifikaları kullanabilir. Java'da özel SSLContext yapılandırması gerekebilir:
Özel SSLContext ile Güvenli İstemci
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.security.cert.X509Certificate;
import java.time.Duration;
public class TlsCustomClient {
// UYARI: Bu trust manager tüm sertifikaları kabul eder
// Sadece test ortamlarında kullanın, üretim için güvenli değil
private static TrustManager[] createInsecureTrustManager() {
return new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
};
}
// Üretim için: Özel CA ile güvenli SSLContext
private static SSLContext createSecureContext() throws Exception {
// Varsayılan SSL context kullan
return SSLContext.getDefault();
}
public static void main(String[] args) throws Exception {
var sslContext = createSecureContext();
var client = HttpClient.newBuilder()
.sslContext(sslContext)
.proxy(java.net.ProxySelector.of(
new InetSocketAddress("gate.proxyhat.com", 8080)
))
.connectTimeout(Duration.ofSeconds(30))
.build();
var request = HttpRequest.newBuilder()
.uri(URI.create("https://httpbin.org/ip"))
.GET()
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
OkHttp ile benzer şekilde, OkHttpClient.Builder.sslSocketFactory() ve hostnameVerifier() metodları kullanılabilir:
import okhttp3.OkHttpClient;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;
import java.time.Duration;
public class OkHttpTlsConfig {
public static OkHttpClient createClientWithCustomTls() throws Exception {
// Varsayılan güvenli SSL context
var sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, null, null);
var trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
};
return new OkHttpClient.Builder()
.sslSocketFactory(sslContext.getSocketFactory(), trustManager)
.connectTimeout(Duration.ofSeconds(30))
.build();
}
}
Üretim İpucu: Yukarıdaki "güvensiz" trust manager örnekleri yalnızca test amaçlıdır. Üretim ortamlarında, güvenilir CA'lar tarafından imzalanmış sertifikalar kullanın veya kurumsal PKI altyapınızı yapılandırın.
HTTP İstemcileri Karşılaştırması
Java ekosistemindeki HTTP istemcilerinin proxy desteği ve özellikleri aşağıdaki tabloda özetlenmiştir:
| Özellik | Java 11+ HttpClient | OkHttp | Apache HttpClient 5 | Jsoup (yerel) |
|---|---|---|---|---|
| Proxy Desteği | ProxySelector | Proxy sınıfı | HttpHost | Sınırlı |
| Kimlik Doğrulama | Authenticator | Authenticator | CredentialsProvider | Yok |
| Bağlantı Havuzu | Otomatik | ConnectionPool | PoolingHttpClient | Yok |
| HTTP/2 | Evet | Evet | Evet | Hayır |
| Async Desteği | CompletableFuture | Call.enqueue() | FutureCallback | Hayır |
| WebSocket | Evet | Evet | Hayır | Hayır |
| Minimum Java | Java 11+ | Java 8+ | Java 8+ | Java 8+ |
En İyi Uygulamalar
- Singleton Pattern: HTTP istemcisi örneklerini yeniden kullanın. Her istek için yeni istemci oluşturmak, bağlantı havuzu avantajını ortadan kaldırır.
- Timeout Yapılandırması: Her zaman connect, read ve write timeout değerlerini ayarlayın. Varsayılan değerler üretim için yetersiz olabilir.
- Resource Yönetimi: Response body'lerini her zaman kapatın (
try-with-resourceskullanın). - Hata İşleme: Ağ hatalarını, timeout'ları ve HTTP hata kodlarını ayrı ayrı ele alın.
- Rate Limiting: Hedef sunucuları aşırı yüklememek için istekler arası bekleme süresi ekleyin.
- User-Agent: Gerçekçi User-Agent header'ları kullanın. Bot tespit sistemleri, varsayılan Java User-Agent'ı engelleyebilir.
Key Takeaways
- Java 11+ HttpClient, modern Java projeleri için önerilen seçenektir; HTTP/2 ve asenkron destek sunar.
- OkHttp, Android ve Java projelerinde mükemmel bir seçimdir; güçlü bağlantı havuzu ve interceptor mekanizması vardır.
- Jsoup proxy kimlik doğrulamasını yerel olarak desteklemez; OkHttp entegrasyonu gerekir.
- Paralel kazıma işlemlerinde, her thread için ayrı session ID kullanarak sticky session sağlanabilir.
- Üretim uygulamalarında timeout, retry ve circuit breaker mekanizmaları zorunludur.
ProxyHat'ın residential proxy havuzu, Java projelerinizde yüksek başarı oranları ve küresel coğrafi hedefleme sunar. Fiyatlandırma sayfasını ziyaret ederek projenize uygun planı seçebilirsiniz.






