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 implicitlyopenConnection() 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.
Was aus dem Programmlauf mitzunehmen ist:
url.openConnection()gab eineURLConnectionzurück, ohne zu verbinden; der Netzwerk-Roundtrip erfolgte erst beim Aufruf vongetInputStream(). 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()undgetContentLength()lesen Antwort-Metadaten, währendgetInputStream()die Nutzdaten liest. Der Server hatContent-Typeexplizit gesetzt, und die Verbindung machte ihn sowohl über den typisierten Getter als auch über das generischegetHeaderField("Content-Type")zugänglich. getContentLength()lieferte die tatsächliche Byteanzahl, weil der Server einenContent-Length-Header gesendet hat. Wenn ein Server ihn weglässt (Chunked-Responses), gibt dies-1zurü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.
URLConnectionist 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 zuHttpURLConnection, was das nächste Kapitel behandelt.