W3docs

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 implicitly

openConnection() 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.

java— editable, runs on the server

O que extrair da execução:

  • url.openConnection() retornou uma URLConnection sem se conectar; a viagem de rede aconteceu apenas quando getInputStream() 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() e getContentLength() leem metadados da resposta, enquanto getInputStream() lê o payload. O servidor definiu Content-Type explicitamente, e a conexão o expôs tanto pelo getter tipado quanto pelo getHeaderField("Content-Type") genérico.
  • getContentLength() retornou a contagem real de bytes porque o servidor enviou um cabeçalho Content-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 para HttpURLConnection, o que o próximo capítulo faz.

Prática

Prática
Uma rotina de download chama 'url.openConnection()' e depois inicia imediatamente um temporizador de 30 segundos antes de chamar 'getInputStream()', esperando que a conexão já esteja aberta. Ela também nunca define nenhum timeout. Qual afirmação está correta?
Uma rotina de download chama 'url.openConnection()' e depois inicia imediatamente um temporizador de 30 segundos antes de chamar 'getInputStream()', esperando que a conexão já esteja aberta. Ela também nunca define nenhum timeout. Qual afirmação está correta?
Was this page helpful?