Para consumir a API de CPF em Java usando o HttpClient nativo, instancie um HttpClient via builder pattern (disponível desde o Java 11), construa a requisição com o header x-api-key e o endpoint GET https://api.cpfhub.io/cpf/{CPF}, depois processe a resposta JSON. O HttpClient suporta tanto chamadas síncronas com send() quanto assíncronas com sendAsync(), sem necessidade de dependências externas para a camada HTTP.
Introdução
A partir do Java 11, a linguagem oferece um HttpClient nativo, moderno e performático que substitui a necessidade de bibliotecas externas como Apache HttpClient ou OkHttp para chamadas HTTP simples. O novo HttpClient suporta HTTP/2, requisições assíncronas e um modelo fluente de configuração.
Configurando o HttpClient
O HttpClient do Java 11+ é criado via builder pattern e pode ser reutilizado para múltiplas requisições.
import java.net.http.HttpClient;
import java.time.Duration;
public class CpfHubClientConfig {
public static HttpClient criarHttpClient() {
return HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.connectTimeout(Duration.ofSeconds(5))
.followRedirects(HttpClient.Redirect.NORMAL)
.build();
}
}
| Configuração | Valor | Descrição |
|---|---|---|
| Versão HTTP | HTTP/2 | Protocolo mais eficiente |
| Connect Timeout | 5 segundos | Tempo máximo para estabelecer conexão |
| Follow Redirects | NORMAL | Segue redirecionamentos padrão |
| Thread Pool | Padrão (ForkJoinPool) | Pool de threads para requisições async |
Consulta síncrona
A abordagem síncrona é a mais simples e adequada para chamadas individuais.
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class CpfHubClient {
private final HttpClient httpClient;
private final String apiKey;
private final String baseUrl;
private final ObjectMapper objectMapper;
public CpfHubClient(String apiKey) {
this.httpClient = CpfHubClientConfig.criarHttpClient();
this.apiKey = apiKey;
this.baseUrl = "https://api.cpfhub.io";
this.objectMapper = new ObjectMapper();
}
public DadosCpf consultar(String cpf) throws Exception {
String cpfLimpo = cpf.replaceAll("\\D", "");
if (cpfLimpo.length() != 11) {
throw new IllegalArgumentException(
"CPF deve conter 11 digitos"
);
}
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(baseUrl + "/cpf/" + cpfLimpo))
.header("x-api-key", apiKey)
.header("Content-Type", "application/json")
.timeout(Duration.ofSeconds(10))
.GET()
.build();
HttpResponse<String> response = httpClient.send(
request,
HttpResponse.BodyHandlers.ofString()
);
return processarResposta(response);
}
private DadosCpf processarResposta(
HttpResponse<String> response) throws Exception {
if (response.statusCode() == 200) {
JsonNode root = objectMapper.readTree(response.body());
if (root.get("success").asBoolean()) {
JsonNode data = root.get("data");
return new DadosCpf(
data.get("cpf").asText(),
data.get("name").asText(),
data.get("nameUpper").asText(),
data.get("gender").asText(),
data.get("birthDate").asText(),
data.get("day").asInt(),
data.get("month").asInt(),
data.get("year").asInt()
);
}
throw new CpfNaoEncontradoException("CPF nao encontrado");
}
if (response.statusCode() == 401) {
throw new AuthenticationException("API key invalida");
}
throw new ApiException(
"Erro na API: status " + response.statusCode()
);
}
}
Modelo de dados e exceções
Defina o record (Java 16+) ou classe para os dados retornados pela API.
// DadosCpf.java
public record DadosCpf(
String cpf,
String name,
String nameUpper,
String gender,
String birthDate,
int day,
int month,
int year
) {
public boolean isMasculino() {
return "M".equals(gender);
}
public boolean isFeminino() {
return "F".equals(gender);
}
}
// Exceções customizadas
public class ApiException extends RuntimeException {
public ApiException(String message) { super(message); }
}
public class CpfNaoEncontradoException extends ApiException {
public CpfNaoEncontradoException(String message) { super(message); }
}
public class AuthenticationException extends ApiException {
public AuthenticationException(String message) { super(message); }
}
| Exceção | Status HTTP | Retentar |
|---|---|---|
| CpfNaoEncontradoException | 200 (success=false) | Não |
| AuthenticationException | 401 | Não |
| ApiException | 5xx | Sim, com backoff |
Consulta assíncrona
O HttpClient oferece suporte nativo a requisições assíncronas via CompletableFuture.
import java.util.concurrent.CompletableFuture;
public class CpfHubAsyncClient {
private final HttpClient httpClient;
private final String apiKey;
private final ObjectMapper objectMapper;
public CpfHubAsyncClient(String apiKey) {
this.httpClient = CpfHubClientConfig.criarHttpClient();
this.apiKey = apiKey;
this.objectMapper = new ObjectMapper();
}
public CompletableFuture<DadosCpf> consultarAsync(String cpf) {
String cpfLimpo = cpf.replaceAll("\\D", "");
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.cpfhub.io/cpf/" + cpfLimpo))
.header("x-api-key", apiKey)
.timeout(Duration.ofSeconds(10))
.GET()
.build();
return httpClient.sendAsync(
request,
HttpResponse.BodyHandlers.ofString()
).thenApply(response -> {
try {
JsonNode root = objectMapper.readTree(response.body());
if (root.get("success").asBoolean()) {
JsonNode data = root.get("data");
return new DadosCpf(
data.get("cpf").asText(),
data.get("name").asText(),
data.get("nameUpper").asText(),
data.get("gender").asText(),
data.get("birthDate").asText(),
data.get("day").asInt(),
data.get("month").asInt(),
data.get("year").asInt()
);
}
throw new CpfNaoEncontradoException("CPF nao encontrado");
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
}
// Uso
CpfHubAsyncClient client = new CpfHubAsyncClient("SUA_API_KEY");
client.consultarAsync("12345678901")
.thenAccept(dados -> System.out.println("Nome: " + dados.name()))
.exceptionally(erro -> {
System.err.println("Erro: " + erro.getMessage());
return null;
});
Exemplo completo de uso
Um exemplo completo demonstrando todas as funcionalidades do cliente.
public class Main {
public static void main(String[] args) {
String apiKey = System.getenv("CPFHUB_API_KEY");
CpfHubClient client = new CpfHubClient(apiKey);
try {
DadosCpf dados = client.consultar("123.456.789-01");
System.out.println("CPF: " + dados.cpf());
System.out.println("Nome: " + dados.name());
System.out.println("Genero: " + dados.gender());
System.out.println("Nascimento: " + dados.birthDate());
System.out.printf("Nascido em %d/%d/%d%n",
dados.day(), dados.month(), dados.year());
} catch (CpfNaoEncontradoException e) {
System.out.println("CPF nao encontrado na base.");
} catch (AuthenticationException e) {
System.out.println("Erro de autenticacao. Verifique a API key.");
} catch (Exception e) {
System.out.println("Erro inesperado: " + e.getMessage());
}
}
}
Perguntas frequentes
O HttpClient nativo do Java 11 é suficiente para consumir a API de CPF em produção?
Sim. O java.net.http.HttpClient suporta HTTP/2, timeouts configuráveis, requisições assíncronas via CompletableFuture e reutilização de conexões — tudo o que é necessário para consumir a API CPFHub.io de forma eficiente em produção, sem adicionar dependências externas ao projeto.
Como configurar timeout para evitar que a aplicação trave em chamadas lentas?
Configure dois timeouts: connectTimeout no builder do HttpClient (recomendado: 5 segundos) e timeout no HttpRequest.newBuilder() (recomendado: 10 segundos). A latência típica da API é de ~900ms, então 10 segundos é margem suficiente para acomodar variações de rede sem prejudicar a experiência do usuário.
Como autenticar as requisições na API CPFHub.io usando Java HttpClient?
Adicione o header x-api-key com sua chave de API ao construir o HttpRequest: .header("x-api-key", apiKey). A chave pode ser armazenada em variável de ambiente (System.getenv("CPFHUB_API_KEY")) para evitar expô-la no código-fonte, seguindo as boas práticas de segurança da OWASP.
Qual a diferença entre send() síncrono e sendAsync() na integração com a API de CPF?
send() bloqueia a thread atual até receber a resposta — ideal para validações pontuais no fluxo de cadastro. sendAsync() retorna um CompletableFuture<HttpResponse> e não bloqueia a thread — ideal para processar múltiplos CPFs em paralelo ou integrar com frameworks reativos. Para validações em batch, sendAsync() com coleta de futures é significativamente mais eficiente.
Conclusão
O HttpClient nativo do Java 11+ é uma solução completa e moderna para consumir a API de CPF, sem necessidade de dependências externas para a camada HTTP. Com suporte a HTTP/2, requisições assíncronas e timeout configurável, o cliente atende desde chamadas individuais simples até cenários de alta concorrência. O tratamento de erros com exceções customizadas garante que cada tipo de falha seja tratado de forma apropriada.
Cadastre-se em cpfhub.io — 50 consultas mensais gratuitas, sem cartão de crédito — e comece a validar CPFs em Java com o HttpClient nativo ainda hoje.
CPFHub.io
Pronto para integrar a API?
50 consultas gratuitas para testar agora. Sem cartão de crédito. Acesso imediato à documentação.
Sobre a redação
Redação CPFHub.io
Time editorial especializado em APIs de CPF, identidade digital e compliance no mercado brasileiro. Produzimos guias técnicos, análises regulatórias e tutoriais sobre LGPD e KYC para desenvolvedores e líderes de produto.



