Java'da HTTP Proxy Kullanımı: HttpClient, OkHttp ve Jsoup ile Tam Rehber

Java 11+ HttpClient, OkHttp ve Jsoup ile HTTP proxy yapılandırmasını öğrenin. Kimlik doğrulama, bağlantı havuzu, yeniden deneme politikaları ve paralel kazıma örnekleri içerir.

Java'da HTTP Proxy Kullanımı: HttpClient, OkHttp ve Jsoup ile Tam Rehber

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-resources kullanı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.

Başlamaya hazır mısınız?

148+ ülkede 50M+ konut IP'sine AI destekli filtreleme ile erişin.

Fiyatlandırmayı GörüntüleKonut Proxy'leri
← Bloga Dön