Introdução: por que preciso de um cliente HTTP em Java?
\n\nO desenvolvimento moderno em Java raramente ocorre sem interação com serviços externos. Seja enviando dados para um servidor, obtendo informações de uma API REST ou integrando-se com plataformas em nuvem — em todos os casos, é necessário um cliente HTTP. Em Java, existem várias maneiras de executar uma requisição HTTP, e é importante escolher a abordagem correta.
\n\nPor muito tempo, a ferramenta padrão foi a biblioteca java.net.HttpURLConnection, mas com o lançamento do Java 11, surgiu um novo módulo mais conveniente: java.net.http. Neste artigo, abordaremos todas as etapas do trabalho com o cliente HTTP em Java: desde requisições GET simples até o envio de JSON e tratamento de erros.
O artigo é voltado para desenvolvedores que já conhecem os fundamentos do Java, mas desejam sistematizar conhecimentos sobre requisições de rede. Usaremos o HttpClient integrado do Java 11+, pois é a abordagem moderna e recomendada.
1. Fundamentos do cliente HTTP: criação e configuração
\n\nAntes de enviar requisições, é necessário criar uma instância de HttpClient. Este é o objeto central através do qual todas as operações HTTP são executadas. Vamos analisar a configuração básica.
Criação do cliente
\n\nA maneira mais simples é usar o método estático newHttpClient():
import java.net.http.HttpClient;\n\nHttpClient client = HttpClient.newHttpClient();\n\nNo entanto, para projetos reais, muitas vezes é necessário configurar timeouts, versão do protocolo ou proxy. Aqui está um exemplo de configuração avançada:
\n\nimport java.net.http.HttpClient;\nimport java.time.Duration;\n\nHttpClient client = HttpClient.newBuilder()\n .version(HttpClient.Version.HTTP_2) // usando HTTP/2\n .connectTimeout(Duration.ofSeconds(10)) // timeout de conexão\n .followRedirects(HttpClient.Redirect.NORMAL) // seguir redirecionamentos automaticamente\n .build();\n\nParâmetros importantes de configuração
\n\n- \n
- version — escolha entre HTTP/1.1 e HTTP/2 (padrão é HTTP/2, se o servidor suportar) \n
- connectTimeout — tempo máximo de espera para conexão \n
- followRedirects — política de tratamento de redirecionamentos (NEVER, ALWAYS, NORMAL) \n
- proxy — configuração de servidor proxy (se necessário) \n
Observe: uma única instância de HttpClient pode ser usada para várias requisições. Ela é thread-safe, portanto pode ser criada uma vez e reutilizada em toda a aplicação.
2. Criação e envio de requisições HTTP
\n\nAgora vamos ao principal — a formação de requisições. No Java 11+, usa-se a classe HttpRequest. Vamos analisar os principais tipos de requisição.
Requisição GET: obtendo dados
\n\nGET é o tipo mais simples de requisição. É usado para obter dados do servidor. Exemplo:
\n\nimport java.net.URI;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\n\nHttpRequest request = HttpRequest.newBuilder()\n .uri(URI.create("https://api.example.com/users"))\n .GET() // especifica explicitamente o método (pode ser omitido, GET é padrão)\n .build();\n\nHttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());\n\nSystem.out.println("Status: " + response.statusCode());\nSystem.out.println("Corpo da resposta: " + response.body());\n\nO método send() executa uma requisição síncrona. Se precisar de execução assíncrona, use sendAsync(), que retorna um CompletableFuture.
Requisição POST: enviando dados
\n\nPOST é usado para enviar dados ao servidor. Na maioria das vezes, são JSON ou formulários. Vamos analisar ambas as opções.
\n\nPOST com JSON:
\n\nimport java.net.http.HttpRequest.BodyPublishers;\n\nString json = "{\\"name\\":\\"João\\",\\"email\\":\\"joa