W3docs

Java URLConnection

Verbindungen zu URLs in Java mit URLConnection öffnen, Ressourcen lesen und Anfragen senden.

Eine URL benennt eine Ressource; eine URLConnection ist die aktive Verbindung, die Sie öffnen, um diese Ressource tatsächlich zu lesen oder zu beschreiben. Sie konstruieren sie nie direkt — Sie rufen url.openConnection() auf, und Java gibt ein Verbindungsobjekt zurück, dessen konkreter Typ vom Protokoll abhängt (http:, https:, file:, jar:, …). URLConnection ist die protokollunabhängige Basisklasse; das Kapitel HttpURLConnection behandelt die HTTP-spezifische Unterklasse.

Diese Seite erklärt, wie man eine Verbindung öffnet, Timeouts konfiguriert, Antwort-Header und den Body liest und wo die protokollneutrale API endet und HTTP-spezifische Arbeit beginnt.

Öffnen und Konfigurieren

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() berührt das Netzwerk nicht — es erstellt lediglich ein konfigurierbares Objekt. Die eigentliche Verbindung erfolgt verzögert, wenn Sie connect() aufrufen oder, häufiger, wenn Sie zum ersten Mal aus getInputStream() lesen. Setzen Sie Timeouts vor dem Verbinden; beide haben standardmäßig den Wert 0, was „unendlich warten" bedeutet — was selten das Gewünschte ist.

Lesen der Antwort

Zwei Arten von Informationen werden zurückgegeben: Header (Metadaten) und der Body (ein Eingabestrom).

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
}

Header-Getter wie getContentType() sind Hilfsmethoden über dem allgemeinen getHeaderField("Name"). Lesen Sie den Body stets mit try-with-resources, damit der zugrundeliegende Socket freigegeben wird.

Daten senden

Um einen Anfrage-Body zu senden, schalten Sie die Verbindung mit setDoOutput(true) in den Ausgabemodus und schreiben dann in getOutputStream(). Bei HTTP bedeutet dies einen POST. Da das Steuern der Methode, des Statuscodes und des Fehlerstroms HTTP-spezifisches Verhalten erfordert, gehört diese Arbeit zu HttpURLConnection.

Ein praktisches Beispiel: Ressource über eine Verbindung lesen

Dieses Programm stellt einen kleinen Text-Body von einem Loopback-HttpServer bereit, öffnet eine generische URLConnection dazu, prüft die Antwort-Header und liest den Body Zeile für Zeile — vollständig offline.

java— editable, runs on the server

Was aus dem Programmlauf mitzunehmen ist:

  • url.openConnection() gab eine URLConnection zurück, ohne zu verbinden; der Netzwerk-Roundtrip erfolgte erst beim Aufruf von getInputStream(). Diese Verzögerung ist der Grund, warum Timeouts und Request-Properties zuerst gesetzt werden müssen — sobald der Body gelesen wird, ist die Verbindung bereits hergestellt und diese Einstellungen sind festgelegt.
  • Die Header-Getter und der Body-Stream sind zwei separate Kanäle. getContentType() und getContentLength() lesen Antwort-Metadaten, während getInputStream() die Nutzdaten liest. Der Server hat Content-Type explizit gesetzt, und die Verbindung machte ihn sowohl über den typisierten Getter als auch über das generische getHeaderField("Content-Type") zugänglich.
  • getContentLength() lieferte die tatsächliche Byteanzahl, weil der Server einen Content-Length-Header gesendet hat. Wenn ein Server ihn weglässt (Chunked-Responses), gibt dies -1 zurück — Code, der einen Puffer anhand dieses Wertes vorab dimensioniert, muss den -1-Fall behandeln.
  • Der Body wurde mit try-with-resources gelesen, was sicherstellt, dass der Socket auch bei einer Ausnahme freigegeben wird. Durch das Auslaufen von Verbindungsstreams erschöpft sich der Verbindungspool und schließlich das OS-Dateideskriptor-Limit — das Schließen ist im Netzwerkcode nicht optional.
  • URLConnection ist bewusst protokollneutral: Nichts hier erwähnte HTTP-Statuscodes oder Request-Methoden. Das Lesen des Status, die Wahl zwischen GET und POST sowie der Zugriff auf den Fehlerstrom erfordern ein Casting zu HttpURLConnection, was das nächste Kapitel behandelt.

Übungen

Übung
Eine Download-Routine ruft 'url.openConnection()' auf und startet dann sofort einen 30-Sekunden-Timer, bevor sie 'getInputStream()' aufruft, in der Erwartung, dass die Verbindung bereits offen ist. Außerdem wird kein Timeout gesetzt. Welche Aussage ist korrekt?
Eine Download-Routine ruft 'url.openConnection()' auf und startet dann sofort einen 30-Sekunden-Timer, bevor sie 'getInputStream()' aufruft, in der Erwartung, dass die Verbindung bereits offen ist. Außerdem wird kein Timeout gesetzt. Welche Aussage ist korrekt?
Was this page helpful?