Screenshot -- Java Code Examples

HTTP-based examples for integrating the Nodium Screenshot API with Java using the built-in java.net.http.HttpClient (Java 11+) and OkHttp.

Basic Screenshot (GET)

The simplest way to capture a screenshot using query parameters and the standard library.

java
import java.io.IOException;
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.nio.file.Files;
import java.nio.file.Path;

public class BasicScreenshot {
    private static final String API_KEY = "YOUR_API_KEY";
    private static final String BASE_URL = "https://api.nodium.io/api/v1/screenshot/take";

    public static void main(String[] args) throws IOException, InterruptedException {
        String url = BASE_URL
            + "?url=" + URLEncoder.encode("https://example.com", StandardCharsets.UTF_8)
            + "&format=png"
            + "&viewport_width=1280"
            + "&viewport_height=1024";

        HttpClient client = HttpClient.newHttpClient();

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(url))
            .header("X-Access-Key", API_KEY)
            .GET()
            .build();

        HttpResponse<byte[]> response = client.send(request, HttpResponse.BodyHandlers.ofByteArray());

        if (response.statusCode() == 200) {
            Files.write(Path.of("screenshot.png"), response.body());
            System.out.println("Screenshot saved (" + response.body().length + " bytes)");
        } else {
            System.err.println("API error (" + response.statusCode() + "): "
                + new String(response.body(), StandardCharsets.UTF_8));
        }
    }
}

POST with JSON Body

Use POST for complex configurations with a JSON request body.

java
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;

public class PostScreenshot {
    private static final String API_KEY = "YOUR_API_KEY";
    private static final String BASE_URL = "https://api.nodium.io/api/v1/screenshot/take";

    public static void main(String[] args) throws IOException, InterruptedException {
        String json = """
            {
                "url": "https://example.com",
                "format": "png",
                "viewport_width": 1440,
                "viewport_height": 900,
                "full_page": true,
                "image_quality": 90,
                "block_ads": true,
                "delay": 1000
            }
            """;

        HttpClient client = HttpClient.newHttpClient();

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(BASE_URL))
            .header("Content-Type", "application/json")
            .header("X-Access-Key", API_KEY)
            .POST(HttpRequest.BodyPublishers.ofString(json))
            .build();

        HttpResponse<byte[]> response = client.send(request, HttpResponse.BodyHandlers.ofByteArray());

        if (response.statusCode() == 200) {
            Files.write(Path.of("screenshot.png"), response.body());

            System.out.println("Screenshot saved");
            response.headers().firstValue("x-nodium-rendering-seconds")
                .ifPresent(v -> System.out.println("Rendering time: " + v + "s"));
            response.headers().firstValue("x-nodium-size-bytes")
                .ifPresent(v -> System.out.println("File size: " + v + " bytes"));
        } else {
            System.err.println("API error (" + response.statusCode() + "): "
                + new String(response.body(), StandardCharsets.UTF_8));
        }
    }
}

Reusable Screenshot Client

A helper class that wraps the API with error handling and retries.

java
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;

public class NodiumClient {
    private static final String BASE_URL = "https://api.nodium.io/api/v1/screenshot";

    private final String apiKey;
    private final HttpClient httpClient;
    private final int maxRetries;

    public NodiumClient(String apiKey) {
        this(apiKey, 3);
    }

    public NodiumClient(String apiKey, int maxRetries) {
        this.apiKey = apiKey;
        this.maxRetries = maxRetries;
        this.httpClient = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(10))
            .build();
    }

    public byte[] take(String jsonBody) throws IOException, InterruptedException {
        return requestWithRetry(BASE_URL + "/take", jsonBody);
    }

    public byte[] animate(String jsonBody) throws IOException, InterruptedException {
        return requestWithRetry(BASE_URL + "/animate", jsonBody);
    }

    private byte[] requestWithRetry(String url, String jsonBody)
            throws IOException, InterruptedException {

        for (int attempt = 0; attempt <= maxRetries; attempt++) {
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Content-Type", "application/json")
                .header("X-Access-Key", apiKey)
                .timeout(Duration.ofSeconds(60))
                .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
                .build();

            HttpResponse<byte[]> response = httpClient.send(
                request, HttpResponse.BodyHandlers.ofByteArray()
            );

            if (response.statusCode() == 200) {
                return response.body();
            }

            String errorBody = new String(response.body(), StandardCharsets.UTF_8);

            // Do not retry client errors (4xx)
            if (response.statusCode() >= 400 && response.statusCode() < 500) {
                throw new IOException("API error (" + response.statusCode() + "): " + errorBody);
            }

            // Retry server errors (5xx) with exponential backoff
            if (attempt < maxRetries) {
                long delay = (long) Math.pow(2, attempt) * 1000;
                System.out.printf("Retry %d/%d after %dms...%n", attempt + 1, maxRetries, delay);
                Thread.sleep(delay);
            }
        }

        throw new IOException("Max retries (" + maxRetries + ") exceeded");
    }
}

Using the Client

java
public class Main {
    public static void main(String[] args) throws Exception {
        NodiumClient client = new NodiumClient("YOUR_API_KEY");

        byte[] screenshot = client.take("""
            {
                "url": "https://example.com",
                "format": "png",
                "viewport_width": 1280,
                "viewport_height": 1024
            }
            """);

        Files.write(Path.of("screenshot.png"), screenshot);
        System.out.println("Screenshot saved (" + screenshot.length + " bytes)");
    }
}

OkHttp Alternative

Using OkHttp for a more ergonomic HTTP client experience.

Maven Dependency

xml
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.12.0</version>
</dependency>

Example

java
import okhttp3.*;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class OkHttpScreenshot {
    private static final String API_KEY = "YOUR_API_KEY";
    private static final String BASE_URL = "https://api.nodium.io/api/v1/screenshot/take";
    private static final MediaType JSON = MediaType.get("application/json");

    public static void main(String[] args) throws IOException {
        OkHttpClient client = new OkHttpClient();

        String json = """
            {
                "url": "https://example.com",
                "format": "png",
                "viewport_width": 1280,
                "viewport_height": 1024,
                "full_page": true
            }
            """;

        Request request = new Request.Builder()
            .url(BASE_URL)
            .header("X-Access-Key", API_KEY)
            .post(RequestBody.create(json, JSON))
            .build();

        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful() && response.body() != null) {
                byte[] bytes = response.body().bytes();
                Files.write(Path.of("screenshot.png"), bytes);
                System.out.println("Screenshot saved (" + bytes.length + " bytes)");
            } else {
                System.err.println("API error (" + response.code() + "): "
                    + (response.body() != null ? response.body().string() : "no body"));
            }
        }
    }
}

Spring Boot Integration

Configuration

yaml
# application.yml
nodium:
  api-key: ${NODIUM_API_KEY}
  base-url: https://api.nodium.io/api/v1/screenshot
  timeout: 60

Configuration Class

java
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConfigurationProperties(prefix = "nodium")
public class NodiumConfig {
    private String apiKey;
    private String baseUrl;
    private int timeout = 60;

    // Getters and setters
    public String getApiKey() { return apiKey; }
    public void setApiKey(String apiKey) { this.apiKey = apiKey; }
    public String getBaseUrl() { return baseUrl; }
    public void setBaseUrl(String baseUrl) { this.baseUrl = baseUrl; }
    public int getTimeout() { return timeout; }
    public void setTimeout(int timeout) { this.timeout = timeout; }

    @Bean
    public NodiumClient nodiumClient() {
        return new NodiumClient(apiKey);
    }
}

REST Controller

java
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/screenshots")
public class ScreenshotController {
    private final NodiumClient nodiumClient;

    public ScreenshotController(NodiumClient nodiumClient) {
        this.nodiumClient = nodiumClient;
    }

    @GetMapping("/capture")
    public ResponseEntity<byte[]> capture(@RequestParam String url) {
        try {
            String json = String.format("""
                {
                    "url": "%s",
                    "format": "png",
                    "viewport_width": 1280,
                    "viewport_height": 1024
                }
                """, url);

            byte[] screenshot = nodiumClient.take(json);

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.IMAGE_PNG);
            headers.setContentDisposition(
                org.springframework.http.ContentDisposition.inline()
                    .filename("screenshot.png")
                    .build()
            );

            return new ResponseEntity<>(screenshot, headers, HttpStatus.OK);

        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(e.getMessage().getBytes());
        }
    }
}

Next Steps