W3docs

Java HttpURLConnection

HTTP-Anfragen in Java mit der HttpURLConnection-API senden und Antworten verarbeiten.

HttpURLConnection ist die HTTP-fähige Unterklasse von URLConnection. Wenn Sie openConnection() auf einer http:- oder https:-URL aufrufen, ist das zurückgegebene Objekt eine HttpURLConnection — casten Sie es, um auf die HTTP-spezifischen Funktionen zuzugreifen: Festlegen der Anfragemethode, Lesen des Statuscodes und Zugriff auf den separaten Fehler-Stream. Es ist der ursprüngliche HTTP-Client des JDK, verfügbar seit Java 1.1.

Dieses Kapitel behandelt das Casten der Verbindung und die Auswahl einer Methode, das Senden eines Anfrage-Bodys, den Statuscode und die zwei Antwort-Streams (die klassische Fehler-Stream-Falle) sowie einen vollständigen POST-Durchlauf, den Sie ausführen können.

Moderner Hinweis: Für neuen Code bevorzugen Sie java.net.http.HttpClient — er ist übersichtlicher, unterstützt HTTP/2 und verarbeitet asynchrone Anfragen. HttpURLConnection ist immer noch in vielen älteren Codebasen verbreitet, daher lohnt es sich, ihn gut zu kennen.

Casten und Methode auswählen

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 akzeptiert "GET", "POST", "PUT", "DELETE" usw. Anfrage-Header fügen Sie mit setRequestProperty hinzu.

Einen Anfrage-Body senden

Um einen Body zu senden, müssen Sie sich mit setDoOutput(true) anmelden (was die Methode standardmäßig auch auf POST setzt), und dann in den Ausgabe-Stream schreiben:

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

Statuscode und die zwei Streams

Das charakteristische HTTP-Merkmal ist der Statuscode, und die daraus folgende Falle:

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

getInputStream() wirft bei einer 4xx/5xx-Antwort eine IOException. Der Fehler-Body befindet sich auf einem anderen Stream, getErrorStream(). Dies zu vergessen ist der klassische HttpURLConnection-Fehler: Eine Fehlerantwort schlägt fehl, anstatt Ihnen zu ermöglichen, die Erklärung des Servers zu lesen. Verzweigen Sie immer zuerst auf getResponseCode(). Beenden Sie mit conn.disconnect().

Ein Praxisbeispiel: ein POST-Durchlauf

Dieses Programm startet einen Loopback-Server, der den Anfrage-Body mit einem 201 Created zurückgibt, und führt dann einen POST über HttpURLConnection durch: Methode setzen, Body schreiben, Status lesen und den richtigen Stream auswählen.

java— editable, runs on the server

Was aus dem Durchlauf mitgenommen werden kann:

  • Das Casten der URLConnection zu HttpURLConnection hat die HTTP-Schicht freigeschaltet: setRequestMethod("POST"), getResponseCode() und getResponseMessage() existieren nur in der Unterklasse. Bei einer http:-URL ist das Objekt tatsächlich eine HttpURLConnection, sodass der Cast immer gelingt.
  • Das Senden eines Bodys erforderte setDoOutput(true) vor dem Schreiben in getOutputStream(). Ohne diesen Aufruf bleibt die Verbindung schreibgeschützt und das Schreiben schlägt fehl — das Aktivieren der Ausgabe ist der Schalter, der ein GET in eine anfrage mit Body verwandelt.
  • getResponseCode() gab 201 zurück und hat tatsächlich die Anfrage an den Server ausgelöst. Der Statuscode ist das Erste, was gelesen werden sollte, da die nächste Entscheidung — welcher Stream gelesen wird — davon abhängt.
  • Das Beispiel verzweigte zwischen getInputStream() und getErrorStream(). Hier ist 201 ein Erfolg, sodass der Eingabe-Stream den zurückgesendeten Body trug, aber bei einer 4xx/5xx-Antwort hätte getInputStream() eine Exception geworfen und die Nachricht des Servers wäre nur über getErrorStream() erreichbar gewesen. Diese Aufteilung ist die schärfste Kante der API.
  • Der Ablauf erforderte mehr als fünf Konfigurationsaufrufe für einen POST und disconnect() zum Aufräumen. Diese Ausführlichkeit — manuelle Streams, die Fehler-Stream-Falle, kein eingebautes Async — ist genau der Grund, warum HttpClient existiert.

Wann HttpURLConnection verwenden

Greifen Sie auf HttpURLConnection zurück, wenn Sie ein älteres JDK (vor Java 11) verwenden, wenn eine Bibliothek oder Codebasis bereits darauf standardisiert ist, oder wenn Sie für einen einzelnen einfachen Aufruf keine zusätzliche Abhängigkeit einbinden möchten. Für alles Neue und Nicht-Triviale — Wiederverwendung von Verbindungen, HTTP/2, Async oder sauberere Anfrage-/Antwortobjekte — bevorzugen Sie den modernen HttpClient. Wenn Sie nur von einer URL lesen müssen, ohne HTTP-spezifische Steuerung, reichen die einfachen Klassen URL und URLConnection aus.

Übung

Übung
Ein Client führt ein PUT mit 'HttpURLConnection' durch. Wenn der Server '400 Bad Request' zurückgibt, stürzt der Code mit einer 'IOException' bei 'conn.getInputStream()' ab, anstatt die Fehlermeldung des Servers zu protokollieren. Was ist die richtige Lösung?
Ein Client führt ein PUT mit 'HttpURLConnection' durch. Wenn der Server '400 Bad Request' zurückgibt, stürzt der Code mit einer 'IOException' bei 'conn.getInputStream()' ab, anstatt die Fehlermeldung des Servers zu protokollieren. Was ist die richtige Lösung?
Was this page helpful?