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.HttpURLConnectionist 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.
Was aus dem Durchlauf mitgenommen werden kann:
- Das Casten der
URLConnectionzuHttpURLConnectionhat die HTTP-Schicht freigeschaltet:setRequestMethod("POST"),getResponseCode()undgetResponseMessage()existieren nur in der Unterklasse. Bei einerhttp:-URL ist das Objekt tatsächlich eineHttpURLConnection, sodass der Cast immer gelingt. - Das Senden eines Bodys erforderte
setDoOutput(true)vor dem Schreiben ingetOutputStream(). 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()gab201zurü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()undgetErrorStream(). Hier ist201ein Erfolg, sodass der Eingabe-Stream den zurückgesendeten Body trug, aber bei einer 4xx/5xx-Antwort hättegetInputStream()eine Exception geworfen und die Nachricht des Servers wäre nur übergetErrorStream()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, warumHttpClientexistiert.
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.