Java Integration
Java integration patterns with zero-dependency core client and Spring Boot configuration.
Copy these patterns into your project to integrate gkCAPTCHA server-side verification.
Installation
Core Client
build.gradle.kts
// Gradle (Kotlin DSL)
dependencies {
implementation("sa.gatekeeper:gkcaptcha-java:0.1.0")
}pom.xml
<!-- Maven -->
<dependency>
<groupId>sa.gatekeeper</groupId>
<artifactId>gkcaptcha-java</artifactId>
<version>0.1.0</version>
</dependency>Spring Boot Starter
build.gradle.kts
// Spring Boot starter — Gradle (Kotlin DSL)
dependencies {
implementation("sa.gatekeeper:gkcaptcha-spring-boot-starter:0.1.0")
}Quick Start
Application.java
import sa.gatekeeper.*;
// Build the client once and reuse it (thread-safe)
GkCaptchaConfig config = GkCaptchaConfig.builder()
.secretKey(System.getenv("GKCAPTCHA_SECRET_KEY"))
.siteKey(System.getenv("GKCAPTCHA_SITE_KEY"))
.build();
GkCaptchaClient client = new GkCaptchaClient(config);
// Synchronous verification
VerifyTokenResponse result = client.verifyToken(captchaToken);
if (!result.success()) {
throw new ForbiddenException("CAPTCHA verification failed: " + result.error());
}
// Asynchronous verification
client.verifyTokenAsync(captchaToken)
.thenAccept(r -> {
if (!r.success()) throw new CompletionException(new ForbiddenException("CAPTCHA failed"));
});Spring Boot Integration
Spring Boot Configuration
application.yml
# application.yml
gkcaptcha:
secret-key: ${GKCAPTCHA_SECRET_KEY}
site-key: ${GKCAPTCHA_SITE_KEY}
api-url: https://gkcaptcha.gatekeeper.sa # optional, default
timeout: 5s # optional, default
max-retries: 1 # optional, default
fail-closed: false # optional, default (fail-open)@RequireCaptcha Annotation
Apply to any controller method. Reads the token from the gk-captcha-token form field or X-Gk-Captcha-Token header.
AuthController.java
import org.springframework.web.bind.annotation.*;
import sa.gatekeeper.spring.RequireCaptcha;
@RestController
public class AuthController {
@PostMapping("/login")
@RequireCaptcha
public ResponseEntity<?> login(@RequestBody LoginRequest req) {
// CAPTCHA has already been verified by the aspect
return ResponseEntity.ok().build();
}
}Route-Level Filter
application.yml
# application.yml — route-level filter
gkcaptcha:
secret-key: ${GKCAPTCHA_SECRET_KEY}
site-key: ${GKCAPTCHA_SITE_KEY}
filter:
enabled: true
url-patterns:
- /api/submit
- /login
- /registerError Handling
By default (fail-open), if the gkCAPTCHA API is unreachable after retries, the client returns a synthetic success response with failOpen() == true. Set failClosed(true) to throw GkCaptchaException instead.
افتراضيًا (فتح عند الفشل)، إذا كانت واجهة gkCAPTCHA غير متاحة، يُرجع العميل استجابة نجاح اصطناعية. لتغيير هذا السلوك استخدم failClosed(true).
ErrorHandling.java
VerifyTokenResponse result = client.verifyToken(token);
if (result.failOpen()) {
log.warn("gkCAPTCHA API unreachable - request allowed through (fail-open)");
}
// To enforce fail-closed:
GkCaptchaConfig config = GkCaptchaConfig.builder()
.secretKey("...")
.siteKey("...")
.failClosed(true) // throws GkCaptchaException("NETWORK_ERROR") on API failure
.build();Environment Variables
| Variable | Required | Description |
|---|---|---|
| GKCAPTCHA_SECRET_KEY | Yes | Secret key from gatekeeper.sa dashboard |
| GKCAPTCHA_SITE_KEY | Yes | Site key from gatekeeper.sa dashboard |
| GKCAPTCHA_API_URL | No | Override API URL (default: https://gkcaptcha.gatekeeper.sa) |