Der HTTP-Standard ist schon relativ alt, und die Ursprünge wurden Anfang der 1990er Jahre gelegt. Offiziell wurde die Version 1.0 im Jahr 1996 verabschiedet, also etwa zu gleichen Zeit, als Java 1.0 erschien. 2015 wurde HTTP/2 verabschiedet, und viele Verbesserungen kamen in den Standard. Die Java-Klassen rund um HTTP wurden allerdings nicht aktualisiert, sodass quelloffene Bibliotheken wie Apache HttpComponents (http://hc.apache.org/) oder die Asynchronous Http and WebSocket Client library for Java (http://github.com/AsyncHttpClient/async-http-client) die Lücken füllten.
1.1.1 Modul java.net.http
Statt die existierenden HTTP-Klassen wie HttpURLConnection um die Neuerungen von HTTP/2 zu erweitern, hat Oracle das Modul java.net.http eingeführt. Erstmalig wurde es in Java 9 im »Brutkasten« (engl. incubator) mit ausgeliefert und in Java 11 festgeschrieben. Neben synchronen Aufrufen können auch asynchrone Aufrufe getätigt werden, die ein modernes CompletableFuture lieferrn.
Das Modul besteht aus einem Paket java.net.http und den wesentlichen Typen:
- HttpClient
- HttpRequest, HttpResponse
- WebSocket
Schauen wir uns ein Beispiel an:
try { URI uri = new URI( "https://tutego.de/" ); HttpRequest request = HttpRequest.newBuilder().uri( uri ).GET().build(); HttpResponse<String> response = HttpClient.newHttpClient().send( request, BodyHandlers.ofString() ); System.out.println( response.body() ); } catch ( URISyntaxException | IOException | InterruptedException e ) { e.printStackTrace(); }
Die Methoden von HttpRequest sind allesamt abstrakt.
abstract class java.net.http.HttpRequest
- Optional<HttpRequest.BodyPublisher> bodyPublisher()
- boolean expectContinue()
- HttpHeaders headers()
- String method()
- Builder newBuilder()
- Builder newBuilder(URI uri)
- Optional<Duration> timeout()
- URI uri()
- Version version()
Führt der HttpClient die Anfrage aus, bekommen wir ein HttpResponse; die Schnittstelle deklariert folgende Methoden:
public interface java.net.http.HttpResponse<T>
- T body()
- HttpHeaders headers()
- Optional<HttpResponse<T>> previousResponse()
- HttpRequest request()
- Optional<SSLSession> sslSession()
- int statusCode()
- URI uri()
- Version version()
Was die Methode body() für einen Typ liefert, bestimmt die Parametrisierung von HttpResponse<T>, und die ergibt sich aus dem übergebenen BodyHandler<T> der HttpClient-Methode send(…):
public abstract class java.net.http.HttpClient
- static HttpClient newHttpClient()
- HttpResponse<T> send(HttpRequest req, HttpResponse.BodyHandler<T> responseBodyHandler)
Der BodyHandler ist eine funktionale Schnittstelle mit einer Methode
- BodySubscriber<T> apply(HttpResponse.ResponseInfo responseInfo)
Es gibt einige vordefinierte Implementierungen in der Klasse HttpResponse.BodyHandlers:
public static class java.net.http.HttpResponse.BodyHandlers
- static HBodyHandler<byte[]> ofByteArray()
- staticBodyHandler<Path> ofFile(Path file)
- static HttpRespoBodyHandler<Stream<String>> ofLines()
- static HBodyHandler<String> ofString()
Weitere Methoden nennt die Javadoc.