This tutorial shows how to integrate CaptchaAI into Java applications using java.net.http.HttpClient (Java 11+). No third-party dependencies required.
Requirements
| Requirement | Details |
|---|---|
| Java | 11+ (HttpClient API) |
| Dependencies | None (standard library) |
| CaptchaAI API key | Get one here |
CaptchaAI Client Class
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Map;
import java.util.stream.Collectors;
public class CaptchaAI {
private final String apiKey;
private final String baseUrl = "https://ocr.captchaai.com";
private final HttpClient httpClient;
public CaptchaAI(String apiKey) {
this.apiKey = apiKey;
this.httpClient = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(30))
.build();
}
/**
* Submit a CAPTCHA task and return the task ID.
*/
public String submit(Map<String, String> params) throws Exception {
params.put("key", apiKey);
String query = buildQuery(params);
String url = baseUrl + "/in.php?" + query;
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.GET()
.build();
HttpResponse<String> response = httpClient.send(
request, HttpResponse.BodyHandlers.ofString());
String body = response.body();
if (!body.startsWith("OK|")) {
throw new RuntimeException("Submit failed: " + body);
}
return body.split("\\|", 2)[1];
}
/**
* Poll for the result with a timeout in seconds.
*/
public String poll(String taskId, int timeoutSeconds) throws Exception {
long deadline = System.currentTimeMillis() + (timeoutSeconds * 1000L);
String query = buildQuery(Map.of(
"key", apiKey,
"action", "get",
"id", taskId
));
String url = baseUrl + "/res.php?" + query;
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.GET()
.build();
while (System.currentTimeMillis() < deadline) {
Thread.sleep(5000);
HttpResponse<String> response = httpClient.send(
request, HttpResponse.BodyHandlers.ofString());
String body = response.body();
if ("CAPCHA_NOT_READY".equals(body)) {
continue;
}
if (body.startsWith("OK|")) {
return body.split("\\|", 2)[1];
}
throw new RuntimeException("Solve failed: " + body);
}
throw new RuntimeException("Timeout after " + timeoutSeconds
+ "s for task " + taskId);
}
/**
* Submit and poll in one call.
*/
public String solve(Map<String, String> params) throws Exception {
String taskId = submit(params);
return poll(taskId, 300);
}
/**
* Check account balance.
*/
public double getBalance() throws Exception {
String query = buildQuery(Map.of(
"key", apiKey,
"action", "getbalance"
));
String url = baseUrl + "/res.php?" + query;
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.GET()
.build();
HttpResponse<String> response = httpClient.send(
request, HttpResponse.BodyHandlers.ofString());
return Double.parseDouble(response.body());
}
private String buildQuery(Map<String, String> params) {
return params.entrySet().stream()
.map(e -> URLEncoder.encode(e.getKey(), StandardCharsets.UTF_8)
+ "="
+ URLEncoder.encode(e.getValue(), StandardCharsets.UTF_8))
.collect(Collectors.joining("&"));
}
}
Solve reCAPTCHA v2
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) throws Exception {
CaptchaAI solver = new CaptchaAI(System.getenv("CAPTCHAAI_API_KEY"));
Map<String, String> params = new HashMap<>();
params.put("method", "userrecaptcha");
params.put("googlekey", "6Le-wvkS...");
params.put("pageurl", "https://example.com");
String token = solver.solve(params);
System.out.println("Token: " + token);
}
}
Solve reCAPTCHA v3
Map<String, String> params = new HashMap<>();
params.put("method", "userrecaptcha");
params.put("googlekey", "6Le-wvkS...");
params.put("pageurl", "https://example.com");
params.put("version", "v3");
params.put("action", "login");
String token = solver.solve(params);
Solve Cloudflare Turnstile
Map<String, String> params = new HashMap<>();
params.put("method", "turnstile");
params.put("sitekey", "0x4AAAAA...");
params.put("pageurl", "https://example.com");
String token = solver.solve(params);
Solve Image CAPTCHAs
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;
byte[] imageBytes = Files.readAllBytes(Path.of("captcha.png"));
String imageB64 = Base64.getEncoder().encodeToString(imageBytes);
Map<String, String> params = new HashMap<>();
params.put("method", "base64");
params.put("body", imageB64);
String text = solver.solve(params);
System.out.println("Text: " + text);
Concurrent Solving with CompletableFuture
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ParallelSolver {
public static void main(String[] args) throws Exception {
CaptchaAI solver = new CaptchaAI(System.getenv("CAPTCHAAI_API_KEY"));
ExecutorService executor = Executors.newFixedThreadPool(10);
List<String> pages = List.of(
"https://example.com/page1",
"https://example.com/page2",
"https://example.com/page3"
);
List<CompletableFuture<String>> futures = new ArrayList<>();
for (String page : pages) {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
Map<String, String> params = new HashMap<>();
params.put("method", "userrecaptcha");
params.put("googlekey", "6Le-wvkS...");
params.put("pageurl", page);
return solver.solve(params);
} catch (Exception e) {
throw new RuntimeException(e);
}
}, executor);
futures.add(future);
}
for (int i = 0; i < futures.size(); i++) {
try {
String token = futures.get(i).get();
System.out.printf("Page %d: solved (%d chars)%n", i, token.length());
} catch (Exception e) {
System.err.printf("Page %d: %s%n", i, e.getMessage());
}
}
executor.shutdown();
}
}
Spring Boot Integration
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CaptchaConfig {
@Bean
public CaptchaAI captchaAI(@Value("${captchaai.api-key}") String apiKey) {
return new CaptchaAI(apiKey);
}
}
# application.yml
captchaai:
api-key: ${CAPTCHAAI_API_KEY}
import org.springframework.web.bind.annotation.*;
@RestController
public class FormController {
private final CaptchaAI solver;
public FormController(CaptchaAI solver) {
this.solver = solver;
}
@PostMapping("/submit")
public Map<String, Object> submit(@RequestBody Map<String, String> body)
throws Exception {
Map<String, String> params = new HashMap<>();
params.put("method", "userrecaptcha");
params.put("googlekey", body.get("siteKey"));
params.put("pageurl", body.get("pageUrl"));
String token = solver.solve(params);
return Map.of("success", true, "tokenLength", token.length());
}
}
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
java.net.ConnectException |
Network issue | Check firewall and DNS |
Submit failed: ERROR_WRONG_USER_KEY |
Bad API key | Copy key from dashboard |
NumberFormatException on balance |
Unexpected response | Check key validity |
Timeout after 300s |
Slow solve or network | Increase timeout; retry |
FAQ
Does this work with Java 8?
The HttpClient API requires Java 11+. For Java 8, use HttpURLConnection or Apache HttpClient with the same API parameters.
Can I use this with Maven/Gradle?
Yes. The code has no external dependencies. Add it as a source file or package it in a local module.
Is the CaptchaAI class thread-safe?
Yes. HttpClient is thread-safe. Use a single CaptchaAI instance across threads.
Discussions (0)
Join the conversation
Sign in to share your opinion.
Sign InNo comments yet.