Java URLConnection
Abra conexões com URLs em Java usando URLConnection para ler recursos e enviar requisições.
Uma URL nomeia um recurso; uma URLConnection é o link ativo que você abre para efetivamente lê-lo ou escrevê-lo. Você nunca a constrói diretamente — você chama url.openConnection(), e o Java retorna um objeto de conexão cujo tipo concreto depende do protocolo (http:, https:, file:, jar:, …). URLConnection é a classe base agnóstica de protocolo; o capítulo HttpURLConnection cobre sua subclasse específica para HTTP.
Esta página explica como abrir uma conexão, configurar timeouts, ler cabeçalhos de resposta e o corpo, e onde a API neutra de protocolo termina e o trabalho específico de HTTP começa.
Abrindo e configurando
URL url = URI.create("http://example.com/data").toURL();
URLConnection conn = url.openConnection(); // not connected yet
conn.setConnectTimeout(2000); // ms to establish the connection
conn.setReadTimeout(2000); // ms to wait for data
conn.connect(); // optional; reading connects implicitlyopenConnection() não toca a rede — apenas cria um objeto configurável. A conexão real acontece de forma preguiçosa quando você chama connect() ou, mais comumente, quando você lê pela primeira vez com getInputStream(). Defina os timeouts antes de conectar; ambos têm padrão 0, significando "esperar para sempre", o que raramente é o que você quer.
Lendo a resposta
Dois tipos de informação retornam: cabeçalhos (metadados) e o corpo (um fluxo de entrada).
String type = conn.getContentType(); // e.g. "text/plain; charset=utf-8"
int length = conn.getContentLength(); // -1 if the server did not send it
long when = conn.getLastModified();
try (InputStream in = conn.getInputStream()) {
// read the body bytes
}Os getters de cabeçalho como getContentType() são atalhos sobre o método geral getHeaderField("Name"). Sempre leia o corpo através de try-with-resources para que o socket subjacente seja liberado.
Enviando dados
Para enviar um corpo de requisição, coloque a conexão em modo de saída com setDoOutput(true), e então escreva em getOutputStream(). Para HTTP, isso implica um POST. Como controlar o método, o código de status e o fluxo de erro requer comportamento específico de HTTP, esse trabalho pertence ao HttpURLConnection.
Um exemplo prático: lendo um recurso por uma conexão
Este programa serve um pequeno corpo de texto a partir de um HttpServer de loopback, abre uma URLConnection genérica para ele, inspeciona os cabeçalhos de resposta e transmite o corpo linha por linha — completamente offline.
O que extrair da execução:
url.openConnection()retornou umaURLConnectionsem se conectar; a viagem de rede aconteceu apenas quandogetInputStream()foi chamado. Essa avaliação preguiçosa é o motivo pelo qual os timeouts e as propriedades da requisição devem ser definidos primeiro — uma vez que você lê o corpo, a conexão já está estabelecida e essas configurações estão bloqueadas.- Os getters de cabeçalho e o fluxo do corpo são dois canais separados.
getContentType()egetContentLength()leem metadados da resposta, enquantogetInputStream()lê o payload. O servidor definiuContent-Typeexplicitamente, e a conexão o expôs tanto pelo getter tipado quanto pelogetHeaderField("Content-Type")genérico. getContentLength()retornou a contagem real de bytes porque o servidor enviou um cabeçalhoContent-Length. Quando um servidor o omite (respostas em chunks), isso retorna-1— portanto, código que pré-dimensiona um buffer a partir dele deve tratar o caso-1.- O corpo foi lido através de try-with-resources, garantindo que o socket seja liberado mesmo em caso de exceção. Vazar fluxos de conexão esgota o pool de conexões e, eventualmente, o limite de descritores de arquivo do SO — fechar não é opcional em código de rede.
URLConnectioné deliberadamente neutra de protocolo: nada aqui mencionou códigos de status HTTP ou métodos de requisição. Ler o status, escolher GET vs POST e acessar o fluxo de erro requerem conversão paraHttpURLConnection, o que o próximo capítulo faz.