W3docs

Java HttpURLConnection

Faça requisições HTTP em Java com a API legada HttpURLConnection.

HttpURLConnection é a subclasse de URLConnection voltada para HTTP. Ao chamar openConnection() em uma URL com esquema http: ou https:, o objeto retornado é um HttpURLConnection — faça o cast para acessar os recursos específicos do HTTP: definir o método da requisição, ler o código de status e obter o stream de erro separado. Trata-se do cliente HTTP original do JDK, disponível desde o Java 1.1.

Este capítulo aborda o cast da conexão e a escolha do método, o envio de um corpo de requisição, o código de status e os dois streams de resposta (a armadilha clássica do error stream), além de um exemplo completo de POST que você pode executar.

Nota moderna: para código novo, prefira java.net.http.HttpClient — é mais limpo, suporta HTTP/2 e lida com operações assíncronas. HttpURLConnection ainda está presente em muitas bases de código legadas, por isso vale a pena conhecê-lo bem.

Cast e escolha do método

URL url = URI.create("http://example.com/api").toURL();
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");                       // GET is the default
conn.setRequestProperty("Content-Type", "application/json");
conn.setConnectTimeout(2000);
conn.setReadTimeout(2000);

setRequestMethod aceita "GET", "POST", "PUT", "DELETE", entre outros. Adicione cabeçalhos de requisição com setRequestProperty.

Envio de um corpo de requisição

Para enviar um corpo, é necessário optar por isso com setDoOutput(true) (o que também define o método padrão como POST) e então escrever no stream de saída:

conn.setDoOutput(true);
try (OutputStream os = conn.getOutputStream()) {
    os.write(payload.getBytes(StandardCharsets.UTF_8));
}

Código de status e os dois streams

O recurso HTTP central é o código de status, e a armadilha que decorre dele:

int code = conn.getResponseCode();          // triggers the request
InputStream body = (code >= 200 && code < 400)
        ? conn.getInputStream()             // success body
        : conn.getErrorStream();            // error body (4xx/5xx)

getInputStream() lança IOException em respostas 4xx/5xx. O corpo do erro fica em um stream diferente, getErrorStream(). Esquecer isso é o bug clássico do HttpURLConnection: uma resposta de erro causa uma exceção em vez de permitir que você leia a explicação do servidor. Sempre verifique getResponseCode() primeiro. Finalize com conn.disconnect().

Um exemplo completo: uma requisição POST de ida e volta

Este programa executa um servidor loopback que ecoa o corpo da requisição de volta com um 201 Created, e então realiza um POST por meio do HttpURLConnection: definindo o método, escrevendo o corpo, lendo o status e escolhendo o stream correto.

java— editable, runs on the server

O que observar na execução:

  • O cast de URLConnection para HttpURLConnection desbloqueou a camada HTTP: setRequestMethod("POST"), getResponseCode() e getResponseMessage() existem apenas na subclasse. Para uma URL com esquema http:, o objeto realmente é um HttpURLConnection, portanto o cast sempre funciona.
  • O envio de um corpo exigiu setDoOutput(true) antes de escrever em getOutputStream(). Sem essa chamada, a conexão permanece somente leitura e a escrita falha — optar pela saída é o interruptor que transforma um GET em uma requisição com corpo.
  • getResponseCode() retornou 201 e é o que de fato disparou a requisição para o servidor. O código de status é a primeira coisa a ser lida, pois a próxima decisão — qual stream ler — depende dele.
  • O exemplo ramificou entre getInputStream() e getErrorStream(). Aqui 201 é sucesso, então o stream de entrada transportou o corpo ecoado, mas em uma resposta 4xx/5xx getInputStream() teria lançado uma exceção e a mensagem do servidor só seria acessível por meio de getErrorStream(). Essa divisão é a aresta mais afiada da API.
  • O fluxo exigiu mais de cinco chamadas de configuração para um único POST, além de disconnect() para encerrar. Essa verbosidade — streams manuais, a armadilha do error stream, sem suporte nativo a operações assíncronas — é exatamente o motivo pelo qual o HttpClient existe.

Quando usar HttpURLConnection

Use HttpURLConnection quando estiver em um JDK mais antigo (anterior ao Java 11), quando uma biblioteca ou base de código já o adota como padrão, ou quando quiser evitar adicionar qualquer dependência extra para uma única chamada simples. Para qualquer coisa nova e não trivial — reutilização de conexão, HTTP/2, operações assíncronas ou objetos de requisição/resposta mais limpos — prefira o moderno HttpClient. Se você só precisa ler de uma URL sem controle específico de HTTP, as classes URL e URLConnection simples são suficientes.

Prática

Prática
Um cliente faz um PUT com 'HttpURLConnection'. Quando o servidor retorna '400 Bad Request', o código falha com uma 'IOException' em 'conn.getInputStream()' em vez de registrar a mensagem de erro do servidor. Qual é a correção correta?
Um cliente faz um PUT com 'HttpURLConnection'. Quando o servidor retorna '400 Bad Request', o código falha com uma 'IOException' em 'conn.getInputStream()' em vez de registrar a mensagem de erro do servidor. Qual é a correção correta?
Was this page helpful?