Java

Exemplos em Java

Seis exemplos prontos para copiar, da primeira chamada ao tratamento de erros, com a certidão de exemplo hospedada (dados fictícios).

Antes de começar

Três passos, uma vez só.

  1. Crie uma chave de API

    No painel, em Chaves de API.

  2. Guarde a chave no ambiente

    Na variável DOCSOCR_API_KEY, que os exemplos leem. O exemplo de preços não precisa de chave.

  3. Salve e rode

    Salve cada exemplo com o nome que aparece sobre o código. As primeiras linhas dizem do que ele precisa para rodar.

Primeira chamada

Envia a certidão de exemplo hospedada (dados fictícios) e mostra o JSON da resposta.

FirstCall.java
// Your first call: extract the hosted sample certificate (fictitious data).
// Needs Java 17+ and DOCSOCR_API_KEY in the environment. Run: java FirstCall.java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.UUID;

public class FirstCall {
    public static void main(String[] args) throws Exception {
        String body = """
            {
              "imageType": "url",
              "imageUrl": "https://docsocr.com/samples/certidao-nascimento-exemplo.jpg",
              "requestId": "%s"
            }""".formatted(UUID.randomUUID()); // one id per document

        HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.docsocr.com/api/v1/documents/birth-certificate"))
            .timeout(Duration.ofSeconds(120)) // above the API's 90 s extraction budget
            .header("Authorization", "Bearer " + System.getenv("DOCSOCR_API_KEY"))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build();
        HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());

        // The answer is JSON: read data.dados_pessoais.nome_completo with your JSON library
        System.out.println(response.body());
        if (response.statusCode() != 201 || !response.body().contains("\"success\":true")) {
            System.exit(1);
        }
    }
}

Arquivo local em base64

Lê uma imagem do seu computador e a envia em base64, sem precisar de uma URL pública.

LocalFile.java
// Extract a certificate from a local file, sent in base64.
// Needs Java 17+ and DOCSOCR_API_KEY in the environment. Run: java LocalFile.java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.Base64;
import java.util.UUID;

public class LocalFile {
    public static void main(String[] args) throws Exception {
        String imageBase64 = Base64.getEncoder().encodeToString(Files.readAllBytes(Path.of("certificate.jpg")));
        String body = """
            {"imageType": "base64", "requestId": "%s", "imageBase64": "%s"}"""
            .formatted(UUID.randomUUID(), imageBase64); // one id per document

        HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.docsocr.com/api/v1/documents/birth-certificate"))
            .timeout(Duration.ofSeconds(120)) // above the API's 90 s extraction budget
            .header("Authorization", "Bearer " + System.getenv("DOCSOCR_API_KEY"))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build();
        HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());

        // The answer is JSON: read data.dados_pessoais.nome_completo with your JSON library
        System.out.println(response.body());
        if (response.statusCode() != 201 || !response.body().contains("\"success\":true")) {
            System.exit(1);
        }
    }
}

Imagem fora do padrão

Com resizeImage: true, uma imagem fora do nosso padrão de tamanho é redimensionada do nosso lado por 1 crédito a mais, em vez de recusada.

Resize.java
// Extract an image outside our standard: resizeImage brings it to the
// standard first, for one extra credit (the 800x640 sample is too small).
// Needs Java 17+ and DOCSOCR_API_KEY in the environment. Run: java Resize.java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.UUID;

public class Resize {
    public static void main(String[] args) throws Exception {
        String body = """
            {
              "imageType": "url",
              "imageUrl": "https://docsocr.com/samples/certidao-nascimento-exemplo-800x640.jpg",
              "requestId": "%s",
              "resizeImage": true
            }""".formatted(UUID.randomUUID()); // one id per document

        HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.docsocr.com/api/v1/documents/birth-certificate"))
            .timeout(Duration.ofSeconds(120)) // above the API's 90 s extraction budget
            .header("Authorization", "Bearer " + System.getenv("DOCSOCR_API_KEY"))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build();
        HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());

        // The answer is JSON: data, imageResized and creditsCharged; read them with your JSON library
        System.out.println(response.body());
        if (response.statusCode() != 201 || !response.body().contains("\"success\":true")) {
            System.exit(1);
        }
    }
}

Motor fast

Pede o motor fast: ele é tentado primeiro, pelo preço dele, e os motores padrão respondem quando ele não consegue. A resposta diz qual motor respondeu e quanto custou.

Fast.java
// Ask for the fast engine: it is tried first, at its own price, and the
// standard engines follow when it cannot answer. The answer names the engine
// that answered and what it cost.
// Needs Java 17+ and DOCSOCR_API_KEY in the environment. Run: java Fast.java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.UUID;

public class Fast {
    public static void main(String[] args) throws Exception {
        String body = """
            {
              "imageType": "url",
              "imageUrl": "https://docsocr.com/samples/certidao-nascimento-exemplo.jpg",
              "requestId": "%s",
              "engine": "fast"
            }""".formatted(UUID.randomUUID()); // one id per document

        HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.docsocr.com/api/v1/documents/birth-certificate"))
            .timeout(Duration.ofSeconds(120)) // above the API's 90 s extraction budget
            .header("Authorization", "Bearer " + System.getenv("DOCSOCR_API_KEY"))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build();
        HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());

        // The answer is JSON: engine and creditsCharged say who answered and the cost
        System.out.println(response.body());
        if (response.statusCode() != 201 || !response.body().contains("\"success\":true")) {
            System.exit(1);
        }
    }
}

Erros e novas tentativas

Trata cada resposta e repete com o mesmo requestId: por 15 minutos, a repetição de uma requisição concluída recebe a mesma resposta, sem nova cobrança, e a de uma ainda em andamento recebe 409, para esperar.

Errors.java
// Extract a certificate, handling every answer, with retries that never charge twice.
// Each retry sends the same requestId: a repeat of a finished request gets its
// kept answer at no charge, and a repeat of one still running is told to wait (409).
// Needs Java 17+ and DOCSOCR_API_KEY in the environment. Run: java Errors.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.time.Duration;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Errors {
    static final String ENDPOINT = "https://api.docsocr.com/api/v1/documents/birth-certificate";
    // No engine could answer: nothing was charged, and a retry may succeed
    static final Set<String> RETRY_LATER = Set.of("EXTRACTION_BUSY", "EXTRACTION_TIMEOUT", "EXTRACTION_UNAVAILABLE");
    // Still in progress, too many requests, the service restarting
    static final Set<Integer> RETRY_STATUS = Set.of(409, 429, 502, 503, 504);
    // Read the answer with your JSON library; this sample only needs two fields
    static final Pattern ERROR_CODE = Pattern.compile("\"errorCode\":\"(\\w+)\"");
    static final Pattern RETRY_AFTER = Pattern.compile("\"retryAfter\":(\\d+)");

    static String extract(String imageUrl, int attempts) throws InterruptedException {
        HttpClient client = HttpClient.newHttpClient();
        String body = """
            {"imageType": "url", "imageUrl": "%s", "requestId": "%s"}"""
            .formatted(imageUrl, UUID.randomUUID()); // one id per document, the same on every retry
        HttpRequest request = HttpRequest.newBuilder(URI.create(ENDPOINT))
            .timeout(Duration.ofSeconds(120)) // above the API's 90 s extraction budget
            .header("Authorization", "Bearer " + System.getenv("DOCSOCR_API_KEY"))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build();

        for (int attempt = 0; attempt < attempts; attempt++) {
            long backoff = 1L << attempt; // seconds: 1, 2, 4, 8
            HttpResponse<String> response;
            try {
                response = client.send(request, HttpResponse.BodyHandlers.ofString());
            } catch (IOException timeoutOrDroppedConnection) {
                Thread.sleep(backoff * 1000);
                continue;
            }
            int status = response.statusCode();
            String answer = response.body();
            if (status == 201 && answer.contains("\"success\":true")) {
                return answer;
            }
            String errorCode = find(ERROR_CODE, answer).orElse("");
            // Wait as long as the answer asks (retryAfter); a limit that resets
            // later, such as a daily quota, is not worth waiting for
            long wait = find(RETRY_AFTER, answer).map(Long::parseLong).orElse(backoff);
            boolean retry = RETRY_LATER.contains(errorCode) || RETRY_STATUS.contains(status);
            if (retry && wait <= 60) {
                Thread.sleep(wait * 1000);
                continue;
            }
            // 400 the body, 401 the key, 402 NOT_ENOUGH_CREDITS, 422 the image
            // (its errorCode says what to fix), DOCUMENT_NOT_RECOGNIZED: fix it, don't retry
            throw new IllegalStateException(status + " " + errorCode + " " + answer);
        }
        throw new IllegalStateException("No answer after retries: try again later");
    }

    static Optional<String> find(Pattern pattern, String text) {
        Matcher match = pattern.matcher(text);
        return match.find() ? Optional.of(match.group(1)) : Optional.empty();
    }

    public static void main(String[] args) throws InterruptedException {
        try {
            System.out.println(extract("https://docsocr.com/samples/certidao-nascimento-exemplo.jpg", 5));
        } catch (IllegalStateException error) {
            System.err.println(error.getMessage());
            System.exit(1);
        }
    }
}

Preços

Consulta o preço de uma extração em créditos, por motor e para o resizeImage. Não precisa de chave.

Prices.java
// The price of an extraction, in credits, per engine and for resizeImage.
// A public endpoint: no key needed. Needs Java 17+. Run: java Prices.java
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 Prices {
    public static void main(String[] args) throws Exception {
        HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.docsocr.com/api/v1/documents/prices"))
            .timeout(Duration.ofSeconds(30))
            .GET()
            .build();
        HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());

        // The answer is JSON, e.g. {"standard": 1, ...}; read it with your JSON library
        System.out.println(response.body());
        if (response.statusCode() != 200) {
            System.exit(1);
        }
    }
}

Pronto para começar?

Crie sua conta, receba créditos grátis e rode o primeiro exemplo com a sua chave.