Cliente HTTP em Java: técnicas avançadas de trabalho com requisições

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Cliente HTTP em Java: fazendo requisições corretamente (nível avançado)



Trabalhar com requisições HTTP é uma das tarefas básicas no desenvolvimento Java moderno. No entanto, escrever código que não apenas envia requisições, mas o faz de forma confiável, com tratamento adequado de erros, timeouts e gerenciamento de recursos, exige um entendimento profundo. Neste artigo, iremos além do simples HttpURLConnection e abordaremos técnicas avançadas de trabalho com clientes HTTP em Java, utilizando o java.net.http.HttpClient nativo (Java 11+) e a biblioteca popular OkHttp.



1. Gerenciamento de timeouts: não deixe sua aplicação travar



Um dos problemas mais comuns ao trabalhar com HTTP é a aplicação travar devido a um servidor lento ou indisponível. Configurar corretamente os timeouts é o primeiro passo para criar um cliente tolerante a falhas.



Tipos de timeouts:

  • Connect Timeout: Tempo de espera para estabelecer a conexão TCP com o servidor.
  • Read Timeout (Socket Timeout): Tempo de espera por dados do servidor após o estabelecimento da conexão.
  • Write Timeout: Tempo de espera para enviar dados ao servidor (relevante para POST/PUT).
  • Request Timeout: Tempo total de execução de toda a requisição HTTP (incluindo conexão, envio e recebimento da resposta).


Exemplo de configuração para java.net.http.HttpClient:

import java.net.http.HttpClient;import java.time.Duration;

public class TimeoutExample { public static HttpClient createClientWithTimeouts() { return HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(5)) // Timeout de conexão .build(); }

public static void main(String[] args) { HttpClient client = createClientWithTimeouts(); // Para timeouts de Leitura/Escrita, usamos HttpRequest var request = java.net.http.HttpRequest.newBuilder() .uri(java.net.URI.create("https://api.example.com/data")) .timeout(Duration.ofSeconds(10)) // Timeout total da requisição .GET() .build(); System.out.println("Cliente com timeouts criado: " + client); }}


Exemplo de configuração para OkHttp:

import okhttp3.OkHttpClient;import java.util.concurrent.TimeUnit;

public class OkHttpTimeoutExample { public static OkHttpClient createOkHttpClient() { return new OkHttpClient.Builder() .connectTimeout(5, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS) .callTimeout(30, TimeUnit.SECONDS) // Timeout total para toda a chamada .build(); }

public static void main(String[] args) { OkHttpClient client = createOkHttpClient(); System.out.println("Cliente OkHttp com timeouts pronto para uso."); }}


2. Pool de conexões e reutilização: economizando recursos



Cada nova conexão HTTP exige custos para estabelecer o handshake TCP e, possivelmente, o handshake TLS. Para aplicações que fazem muitas requisições ao mesmo servidor, é fundamental usar um pool de conexões (connection pool). Isso permite reutilizar conexões existentes, acelerando significativamente as requisições e reduzindo a carga na rede.



java.net.http.HttpClient possui um pool de conexões embutido, gerenciado automaticamente. No entanto, você pode configurar seu tamanho:

import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;import java.net.URI;import java.time.Duration;

public class PoolExample { public static void main(String[] args) throws Exception { // HttpClient gerencia o pool automaticamente, mas podemos limit

Blogs

Book Recommendations