Spring Boot'tan CAPTCHA API'sini çağırın

solvethree tarafından4 dk okuma

Sunucu tarafında bir CaptchaClient bean’i kaydedin, görevi bir kez oluşturun, ardından kaydettiğiniz kimlikle durumunu sorgulayın. Aşağıdaki yardımcı sınıf, senkron Spring RestClient çağrıları kullanır ve Gson JsonObject yanıtları döndürür.

Bu sayfada

Bağımlılıkları ekleyin ve yardımcı sınıfı kaydedin

Sağlanan yardımcı sınıf Java 21+, Spring Web 7.0.10 ve Gson 2.15.0 kullanır. Mevcut bir Spring Boot projesinde, örnekle eşleştirmek için yalnızca spring-web sürümünü geçersiz kılmak yerine Boot’un yönettiği uyumlu Spring sürümünü koruyun. Uygulamanızda henüz yoksa Gson’u bağımlılık olarak ekleyin.

Spring · sunucu tarafında bir RestClient servisi
// Java 21+, Spring Web 7.0.10 and Gson 2.15.0; use your Boot dependency management.
// Save as CaptchaClient.java in your application's package.
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.net.http.HttpClient;
import java.time.Duration;
import org.springframework.http.MediaType;
import org.springframework.http.client.JdkClientHttpRequestFactory;
import org.springframework.web.client.RestClient;

public final class CaptchaClient {
    private final RestClient api;
    public CaptchaClient(String key) {
        var transport = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10))
            .followRedirects(HttpClient.Redirect.NEVER).build();
        var factory = new JdkClientHttpRequestFactory(transport);
        factory.setReadTimeout(Duration.ofSeconds(25));
        api = RestClient.builder().baseUrl("https://api.solvethree.com/v1")
            .requestFactory(factory).defaultHeader("Authorization", "Bearer " + key).build();
    }
    public JsonObject create(String site, String proxy, String requestId) {
        var input = new JsonObject();
        input.addProperty("site", site);
        input.addProperty("action", "login");
        input.addProperty("proxy", proxy);
        input.addProperty("requestId", requestId); // Save before calling create.
        String body = api.post().uri("/tasks?waitMs=0").contentType(MediaType.APPLICATION_JSON)
            .body(input.toString()).retrieve().body(String.class);
        return JsonParser.parseString(body).getAsJsonObject();
    }
    public JsonObject get(String id) {
        if (!id.matches("[A-Za-z0-9_-]+")) throw new IllegalArgumentException("Invalid task ID");
        String body = api.get().uri("/tasks/{id}?waitMs=15000", id)
            .retrieve().body(String.class);
        return JsonParser.parseString(body).getAsJsonObject();
    }
}
// Construct once with System.getenv("SOLVETHREE_API_KEY") in a server-side @Bean.
// Call create once, save its id, then get(id) until ready/failed or your deadline.
// RestClient throws on HTTP errors; keep the saved requestId and any known task id.

Sınıfı uygulamanızın paketinde CaptchaClient.java olarak kaydedin. Sunucu tarafındaki bir @Bean fabrika metodunda, SOLVETHREE_API_KEY ortam değişkenini kullanarak bir kez oluşturun. Başlangıçta anahtarın yapılandırıldığını kontrol edin. Yardımcı sınıf bu anahtarı Bearer yetkilendirme üstbilgisi olarak ekler; anahtarı tarayıcı koduna dahil etmeyin.

Bu bean’i kurucu enjeksiyonu yoluyla yeniden kullanın. RestClient iş parçacıkları arasında yeniden kullanılabilir, ancak her istek kendisini çağıran iş parçacığını bloklar. Bu metotları bir WebFlux olay döngüsünde çağırmayın. Spring’in REST istemcisi belgeleri senkron istemciyi açıklar.

Aktarım katmanı 10 saniyelik bağlantı zaman aşımı ve 25 saniyelik okuma zaman aşımı kullanır; yönlendirmeleri izlemez. Yanıtlar metin olarak okunup Gson ile ayrıştırılır; türlendirilmiş yanıt nesnelerine eşlenmez.

Siteyi, eylemi ve proxy’yi ayarlayın

create çağrısından önce çalışma alanınızda hedef site için etkin bir profil yapılandırın. Ana makine adı ve eylem göndermek bu profili oluşturmaz. Site henüz yapılandırılmadıysa site profili kurulumuna bakın.

  • site olarak tam sayfa URL’sini değil, ana makine adını iletin. reCAPTCHA isteğinde url veya type alanı bulunmaz.
  • Yardımcı sınıf action değerini login olarak sabitler. Amaçlanan istek farklı bir eylem kullanıyorsa bu değeri değiştirin veya metot parametresi hâline getirin.
  • Bir proxy URL’si iletin. API, proxy veya proxyCandidates alanlarından tam olarak birini gerektirir; bu yardımcı sınıf tek proxy seçeneğini uygular.
  • Yardımcı sınıf recaptchaType alanını göndermez; bu nedenle API varsayılan enterprise-v3 değerini kullanır.

Bir kez oluşturun, ardından kaydedilen görev kimliğiyle durumu sorgulayın

  1. 1.

    Oluşturmadan önce bir istek kimliği kaydedin

    1–64 ASCII harfi, rakam, alt çizgi veya kısa çizgi içeren bir requestId seçin. create çağrısından önce bunu görev girdileriyle birlikte kaydedin. Oluşturma yanıtı kaybolursa aynı göreve yeniden erişmenizi sağlar.

  2. 2.

    create çağrısını yapın ve dönen id değerini kaydedin

    Bean’in create metodunu ana makine adı, proxy ve kaydedilen istek kimliğiyle çağırın. Bu metot, /v1/tasks adresine waitMs=0 ile tek bir POST isteği gönderir. Dönen id değerini kaydedin; sonraki sorgulamalarda istek kimliğini değil, bu görev kimliğini kullanın.

  3. 3.

    Görev nihai bir duruma ulaşana kadar get çağrısı yapın

    Kaydedilen görev kimliğini get metoduna iletin. Her sorgulama waitMs=15000 ister ve yanıtı beklerken çağıran iş parçacığını bloklar. Uygulama düzeyindeki son süreyi aşmadan pending veya solving durumlarında devam edin. ready veya failed durumlarında durun. HTTP zaman aşımları tüm sorgulama döngüsünü değil, tek tek istekleri sınırlar.

  4. 4.

    Çözümü yalnızca hazır olduğunda okuyun

    reCAPTCHA için amaçlanan hedefe görev kimliğini değil, solution.token değerini gönderin. Dönen userAgent ve secChUa değerlerini çözümün başarıyla elde edildiği aynı proxy ile kullanın. Bunların yerine ilgisiz tarayıcı üstbilgileri kullanmayın veya hedef URL’yi değiştirmeyin. Hazır bir görev çözüm sağlar; hedefin sonraki isteğinizi kabul ettiğini göstermez.

HTTP hatalarını başarısız görevlerden ayrı ele alın

Oluşturma çağrısı, görev kimliğini almadan önce zaman aşımına uğrar.

İstemciniz yanıtı almamış olsa da sunucu görevi oluşturmuş olabilir.

Şunu deneyin: Aynı görev isteğini kaydedilen requestId ile tekrarlayarak göreve yeniden erişin. Eşleşen girdiler mevcut görevi döndürür. Yeni bir mantıksal görev oluşturmayı amaçlamıyorsanız yeni bir istek kimliği üretmeyin.

Bir get çağrısı HTTP katmanında başarısız olur.

RestClient.retrieve(), başarılı olmayan HTTP yanıtlarında istisna fırlatır. Bu, görevin failed durumunda olduğu anlamına gelmez.

Şunu deneyin: Başarı yanıtının içeriğini okumaya çalışmadan önce HTTP hatasını ele alın. Başka bir görev oluşturmak yerine, göreve yeniden erişebilmek için bilinen görev kimliğini saklayın. Geçersiz girdileri değiştirmeden yeniden denemeden önce sorunu teşhis edin.

Görev yanıtının durumu failed olur.

Görevin errorCode ve error alanlarını okuyun; site-unreachable, olası görev hata kodlarından biridir.

Şunu deneyin: Bu görevin durumunu sorgulamayı bırakın ve başka bir görev başlatmadan önce bildirilen nedeni giderin. Başarısız çözümlerin ücreti iade edilir; başarısızlığın yetersiz kredi anlamına geldiğini varsaymayın.

Bir istek kimliğini yeniden kullanmak çakışmaya yol açar.

Yeni görev girdilerini, bu istek kimliği için kaydedilen girdilerle karşılaştırın.

Şunu deneyin: Mevcut göreve yeniden erişmek için özgün girdileri kullanın. Bilerek farklı görev girdileri kullanıyorsanız yeni bir istek kimliği kullanın.

Hataları yorumlamak için CAPTCHA API hatalarına bakın.

İlk görevinizi çalıştırın.

$5 çalışma alanı kredisiyle başlayın.

Çalışma alanı oluşturun
Spring Boot'tan CAPTCHA API'sini çağırın · solvethree