Het verkennen van de nieuwe HTTP-client in Java

1. Inleiding

In deze tutorial zullen we de nieuwe incubatie van Java 9 verkennen HttpClient.

Tot voor kort leverde Java alleen het HttpURLConnection API - die van een laag niveau is en niet bekend staat als rijk aan functiesengebruikersvriendelijk.

Daarom werden een aantal veelgebruikte bibliotheken van derden vaak gebruikt, zoals Apache HttpClient, Jetty en Spring's RestTemplate.

2. Eerste installatie

De HTTP Client-module is gebundeld als incubatormodule in JDK 9 en ondersteunt HTTP / 2, terwijl achterwaartse compatibiliteit nog steeds HTTP / 1.1 mogelijk maakt.

Om het te gebruiken, moeten we onze module definiëren met een module-info.java bestand dat ook de vereiste module aangeeft om onze applicatie uit te voeren:

module com.baeldung.java9.httpclient {vereist jdk.incubator.httpclient; }

3. HTTP Client API-overzicht

in tegenstelling tot HttpURLConnectie, HTTP Client biedt synchrone en asynchrone aanvraagmechanismen.

De API bestaat uit 3 kernklassen:

  • HttpRequeststaat voor het verzoek dat moet worden verzonden via de HttpClient
  • HttpClientgedraagt ​​zich als een container voor configuratiegegevens die gemeenschappelijk zijn voor meerdere verzoeken
  • HttpResponsevertegenwoordigt het resultaat van een HttpRequest bellen

In de volgende secties zullen we ze allemaal in meer detail onderzoeken. Laten we ons eerst concentreren op een verzoek.

4. HttpRequest

HttpRequest, als de naam suggereert, is een object dat een verzoek vertegenwoordigt dat we willen verzenden. Met HttpRequest.Builder.

We kunnen het krijgen door te bellen HttpRequest.newBuilder (). Bouwer class biedt een aantal methoden die we kunnen gebruiken om ons verzoek te configureren.

We behandelen de belangrijkste.

4.1. Instelling URI

Het eerste dat we moeten doen bij het maken van een verzoek, is de URL opgeven.

We kunnen dat op twee manieren doen - door de constructor voor te gebruiken Bouwer met URI parameter of door methode aan te roepen uri (URI) op de Bouwer voorbeeld:

HttpRequest.newBuilder (nieuwe URI ("// postman-echo.com/get")) HttpRequest.newBuilder () .uri (nieuwe URI ("// postman-echo.com/get"))

Het laatste dat we moeten configureren om een ​​basisverzoek te maken, is een HTTP-methode.

4.2. Specificeren van de HTTP-methode

We kunnen de HTTP-methode definiëren die ons verzoek zal gebruiken door een van de methoden aan te roepen van Bouwer:

  • KRIJGEN()
  • POST (BodyProcessor body)
  • PUT (BodyProcessor-lichaam)
  • DELETE (BodyProcessor body)

We dekken BodyProcessor in detail, later. Laten we nu gewoon creëren een heel eenvoudig voorbeeld van een GET-verzoek:

HttpRequest request = HttpRequest.newBuilder () .uri (nieuwe URI ("// postman-echo.com/get")) .GET () .build ();

Dit verzoek bevat alle parameters die vereist zijn voor HttpClient. Soms moeten we echter extra parameters aan ons verzoek toevoegen; hier zijn enkele belangrijke:

  • de versie van het HTTP-protocol
  • headers
  • een time-out

4.3. HTTP-protocolversie instellen

De API maakt volledig gebruik van het HTTP / 2-protocol en gebruikt het standaard, maar we kunnen bepalen welke versie van het protocol we willen gebruiken.

HttpRequest request = HttpRequest.newBuilder () .uri (nieuwe URI ("// postman-echo.com/get")) .version (HttpClient.Version.HTTP_2) .GET () .build ();

Belangrijk om hier te vermelden is dat de client zal terugvallen op bijvoorbeeld HTTP / 1.1 als HTTP / 2 niet wordt ondersteund.

4.4. Headers instellen

Als we extra headers aan ons verzoek willen toevoegen, kunnen we de meegeleverde builder-methoden gebruiken.

We kunnen dat op twee manieren doen:

  • alle headers doorgeven als sleutel / waarde-paren aan de headers () methode of door
  • gebruik makend van koptekst () methode voor de single key-value header:
HttpRequest request = HttpRequest.newBuilder () .uri (nieuwe URI ("// postman-echo.com/get")) .headers ("key1", "value1", "key2", "value2") .GET () .bouwen(); HttpRequest request2 = HttpRequest.newBuilder () .uri (nieuwe URI ("// postman-echo.com/get")) .header ("key1", "value1") .header ("key2", "value2"). GET () .build (); 

De laatste handige methode die we kunnen gebruiken om ons verzoek aan te passen, is een time-out ().

4.5. Een time-out instellen

Laten we nu bepalen hoe lang we op een antwoord willen wachten.

Als de ingestelde tijd is verstreken, a HttpTimeoutException zal worden gegooid; de standaard time-out is ingesteld op oneindig.

De time-out kan worden ingesteld met de Looptijd object - door methode aan te roepen time-out() op de builder-instantie:

HttpRequest request = HttpRequest.newBuilder () .uri (nieuwe URI ("// postman-echo.com/get")) .timeout (Duration.of (10, SECONDS)) .GET () .build ();

5. Instellen van een verzoekorgaan

We kunnen een hoofdtekst aan een verzoek toevoegen met behulp van de methoden voor het maken van verzoeken: POST (BodyProcessor body), PUT (BodyProcessor-lichaam) en DELETE (BodyProcessor body).

De nieuwe API biedt een aantal BodyProcessor implementaties out-of-the-box die het passeren van de hoofdtekst van het verzoek vereenvoudigen:

  • StringProcessor (leest het hoofdgedeelte van een Draad, gemaakt met HttpRequest.BodyProcessor.fromString)
  • InputStreamProcessor (leest het lichaam van een InputStream, gemaakt met HttpRequest.BodyProcessor.fromInputStream)
  • ByteArrayProcessor (leest body van een byte-array, gemaakt met HttpRequest.BodyProcessor.fromByteArray)
  • FileProcessor (leest body uit een bestand op het opgegeven pad, gemaakt met HttpRequest.BodyProcessor.fromFile)

Als we geen lichaam nodig hebben, kunnen we gewoon een HttpRequest.noBody ():

HttpRequest request = HttpRequest.newBuilder () .uri (nieuwe URI ("// postman-echo.com/post")) .POST (HttpRequest.noBody ()) .build ();

5.1. StringBodyProcessor

Een verzoektekst instellen met elk BodyProcessor implementatie is heel eenvoudig en intuïtief.

Als we bijvoorbeeld een simple willen doorgeven Draad als lichaam kunnen we gebruiken StringBodyProcessor.

Zoals we al zeiden, kan dit object worden gemaakt met een fabrieksmethode fromString (); het duurt slechts een Draad object als argument en maakt er een body van:

HttpRequest request = HttpRequest.newBuilder () .uri (nieuwe URI ("// postman-echo.com/post")) .headers ("Content-Type", "text / plain; charset = UTF-8") .POST (HttpRequest.BodyProcessor.fromString ("Sample request body")) .build (); 

5.2. InputStreamBodyProcessor

Om dat te doen, de InputStream moet worden doorgegeven als een Leverancier (om de creatie lui te maken), dus het is een beetje anders dan hierboven beschreven StringBodyProcessor.

Dit is echter ook vrij eenvoudig:

byte [] sampleData = "Voorbeeld van aanvraagtekst" .getBytes (); HttpRequest request = HttpRequest.newBuilder () .uri (nieuwe URI ("// postman-echo.com/post")) .headers ("Content-Type", "text / plain; charset = UTF-8") .POST (HttpRequest.BodyProcessor .fromInputStream (() -> nieuwe ByteArrayInputStream (sampleData))) .build (); 

Merk op hoe we een simple hebben gebruikt ByteArrayInputStream hier; dat kan natuurlijk elk zijn InputStream implementatie.

5.3. ByteArrayProcessor

We kunnen ook gebruik maken van ByteArrayProcessor en geef een reeks bytes door als parameter:

byte [] sampleData = "Voorbeeld van aanvraagtekst" .getBytes (); HttpRequest request = HttpRequest.newBuilder () .uri (nieuwe URI ("// postman-echo.com/post")) .headers ("Content-Type", "text / plain; charset = UTF-8") .POST (HttpRequest.BodyProcessor.fromByteArray (sampleData)) .build ();

5.4. FileProcessor

Om met een bestand te werken, kunnen we gebruik maken van het verstrekte FileProcessor; de fabrieksmethode neemt een pad naar het bestand als parameter en maakt een body van de inhoud:

HttpRequest request = HttpRequest.newBuilder () .uri (nieuwe URI ("// postman-echo.com/post")) .headers ("Content-Type", "text / plain; charset = UTF-8") .POST (HttpRequest.BodyProcessor.fromFile (Paths.get ("src / test / resources / sample.txt"))) .build ();

We hebben besproken hoe je kunt creëren HttpRequest en hoe u er aanvullende parameters in kunt instellen.

Nu is het tijd om er dieper naar te kijken HttpClient class die verantwoordelijk is voor het verzenden van verzoeken en het ontvangen van antwoorden.

6. HttpClient

Alle verzoeken worden verzonden met HttpClient die kan worden geïnstantieerd met behulp van de HttpClient.newBuilder () methode of door te bellen HttpClient.newHttpClient ().

Het biedt veel nuttige en zichzelf beschrijvende methoden die we kunnen gebruiken om ons verzoek / antwoord af te handelen.

Laten we er hier een paar bespreken.

6.1. Een proxy instellen

We kunnen een proxy voor de verbinding definiëren. Gewoon bellen volmacht () methode op een Bouwer voorbeeld:

HttpResponse response = HttpClient .newBuilder () .proxy (ProxySelector.getDefault ()) .build () .send (verzoek, HttpResponse.BodyHandler.asString ()); 

In ons voorbeeld hebben we de standaard systeemproxy gebruikt.

6.2. Het omleidingsbeleid instellen

Soms is de pagina die we willen openen naar een ander adres verplaatst.

In dat geval ontvangen we HTTP-statuscode 3xx, meestal met de informatie over de nieuwe URI. HttpClient kan het verzoek automatisch omleiden naar de nieuwe URI als we het juiste omleidingsbeleid instellen.

We kunnen het doen met de followRedirects () methode op Bouwer:

HttpResponse antwoord = HttpClient.newBuilder () .followRedirects (HttpClient.Redirect.ALWAYS) .build () .send (verzoek, HttpResponse.BodyHandler.asString ());

Alle beleidsregels zijn gedefinieerd en beschreven in enum HttpClient.Redirect.

6.3. Instelling Authenticator voor een verbinding

Een Authenticator is een object dat inloggegevens (HTTP-authenticatie) voor een verbinding onderhandelt.

Het biedt verschillende authenticatieschema's (zoals bijvoorbeeld basis- of digest-authenticatie). In de meeste gevallen zijn voor authenticatie een gebruikersnaam en wachtwoord vereist om verbinding te maken met een server.

We kunnen gebruiken WachtwoordVerificatie klasse die slechts een houder is van deze waarden:

HttpResponse response = HttpClient.newBuilder () .authenticator (nieuwe Authenticator () {@Override beschermde PasswordAuthentication getPasswordAuthentication () {retourneer nieuwe PasswordAuthentication ("gebruikersnaam", "wachtwoord" .toCharArray ());}}). Build () .send (verzoek, HttpResponse.BodyHandler.asString ());

In het bovenstaande voorbeeld hebben we de gebruikersnaam en het wachtwoord als leesbare tekst doorgegeven; natuurlijk zal dit in een productiescenario anders moeten zijn.

Houd er rekening mee dat niet voor elk verzoek dezelfde gebruikersnaam en hetzelfde wachtwoord moet worden gebruikt. De Authenticator klasse biedt een aantal getXXX (bijv. getRequestingSite ()) methoden die kunnen worden gebruikt om erachter te komen welke waarden moeten worden opgegeven.

Nu gaan we een van de handigste functies van nieuwe HttpClient - asynchrone oproepen naar de server.

6.4. Verzoeken verzenden - Synchronisatie versus async

Nieuwe HttpClient biedt twee mogelijkheden om een ​​verzoek naar een server te sturen:

  • sturen(…) - synchroon (blokkeert totdat het antwoord komt)
  • sendAsync (…) - asynchroon (wacht niet op het antwoord, niet-blokkerend)

Tot nu toe heeft de sturen(...) methode wacht natuurlijk op een antwoord:

HttpResponse antwoord = HttpClient.newBuilder () .build () .send (verzoek, HttpResponse.BodyHandler.asString ()); 

Deze aanroep retourneert een HttpResponse object, en we zijn er zeker van dat de volgende instructie uit onze applicatiestroom alleen zal worden uitgevoerd als het antwoord er al is.

Het heeft echter veel nadelen, vooral wanneer we grote hoeveelheden gegevens verwerken.

Dus nu kunnen we gebruiken sendAsync (...) methode - die terugkeert CompletableFeatureom een ​​verzoek asynchroon te verwerken:

CompletableFuture response = HttpClient.newBuilder () .build () .sendAsync (verzoek, HttpResponse.BodyHandler.asString ());

De nieuwe API kan ook meerdere reacties verwerken en de verzoek- en reactie-instanties streamen:

Lijstdoelen = Arrays.asList (nieuwe URI ("// postman-echo.com/get?foo1=bar1"), nieuwe URI ("// postman-echo.com/get?foo2=bar2")); HttpClient-client = HttpClient.newHttpClient (); Lijst futures = targets.stream () .map (target -> client .sendAsync (HttpRequest.newBuilder (target) .GET (). build (), HttpResponse.BodyHandler.asString ()) .thenApply (antwoord -> response.body ( ))) .collect (Collectors.toList ());

6.5. Instelling Uitvoerder voor asynchrone oproepen

We kunnen ook een Uitvoerder die threads biedt die kunnen worden gebruikt door asynchrone oproepen.

Op deze manier kunnen we bijvoorbeeld het aantal threads beperken dat wordt gebruikt voor het verwerken van verzoeken:

ExecutorService executorService = Executors.newFixedThreadPool (2); CompletableFuture response1 = HttpClient.newBuilder () .executor (executorService) .build () .sendAsync (verzoek, HttpResponse.BodyHandler.asString ()); CompletableFuture response2 = HttpClient.newBuilder () .executor (executorService) .build () .sendAsync (verzoek, HttpResponse.BodyHandler.asString ());

Standaard is het HttpClient gebruikt uitvoerder java.util.concurrent.Executors.newCachedThreadPool ().

6.6. Een Cookie Manager

Met de nieuwe API en builder is het eenvoudig om een Cookie Manager voor onze verbinding. We kunnen de bouwer-methode gebruiken cookieManager (CookieManager cookieManager) om klantspecifiek te definiëren Cookie Manager.

Laten we bijvoorbeeld definiëren Cookie Manager die helemaal geen cookies toestaat:

HttpClient.newBuilder () .cookieManager (nieuwe CookieManager (null, CookiePolicy.ACCEPT_NONE)) .build (); 

Voor het geval dat onze Cookie Manager toestaan ​​dat cookies worden opgeslagen, we kunnen er toegang toe krijgen door aan te vinken Cookie Manager van onze HttpClient:

httpClient.cookieManager (). get (). getCookieStore () 

Laten we ons nu concentreren op de laatste klasse van Http API - het HttpResponse.

7. HttpResponse Voorwerp

De HttpResponse class vertegenwoordigt het antwoord van de server. Het biedt een aantal handige methoden, maar de twee belangrijkste zijn:

  • status code() - geeft statuscode terug (type int) voor een reactie (HttpURLConnection klasse bevat mogelijke waarden)
  • lichaam() - retourneert een hoofdtekst voor een antwoord (retourtype hangt af van het antwoord BodyHandler parameter doorgegeven aan de sturen() methode)

Het responsobject heeft een andere handige methode die we zullen behandelen, zoals uri (), headers (), aanhangwagens en versie().

7.1. URI van Response Object

De methode uri () op het antwoordobject retourneert de URI waarvan we de reactie hebben ontvangen.

Soms kan het anders zijn dan URI in het request-object, omdat een omleiding kan plaatsvinden:

assertThat (request.uri () .toString (), equalTo ("// stackoverflow.com")); assertThat (response.uri () .toString (), equalTo ("// stackoverflow.com/"));

7.2. Headers van Response

We kunnen kopteksten uit het antwoord halen door de methode aan te roepen headers () op een antwoordobject:

HttpResponse antwoord = HttpClient.newHttpClient () .send (verzoek, HttpResponse.BodyHandler.asString ()); HttpHeaders responseHeaders = response.headers ();

Het keert terug HttpHeaders object als een retourtype. Dit is een nieuw type gedefinieerd in jdk.incubator.http pakket dat een alleen-lezen weergave van HTTP-headers vertegenwoordigt.

Het heeft een aantal handige methoden die het zoeken naar de waarde van kopteksten vereenvoudigen.

7.3. Krijg trailers van Response

Het HTTP-antwoord kan aanvullende kopteksten bevatten die worden opgenomen na de inhoud van het antwoord. Deze headers worden trailer headers genoemd.

We kunnen ze verkrijgen door methode aan te roepen aanhangwagens Aan HttpResponse:

HttpResponse antwoord = HttpClient.newHttpClient () .send (verzoek, HttpResponse.BodyHandler.asString ()); CompletableFuture trailers = response.trailers (); 

Let daar op aanhangwagens methode retourneert CompletableFuture voorwerp.

7.4. Versie van het antwoord

De methode versie() definieert welke versie van het HTTP-protocol is gebruikt om met een server te praten.

Onthoud dat zelfs als we definiëren dat we HTTP / 2 willen gebruiken, de server kan antwoorden via HTTP / 1.1.

De versie waarin de server antwoordde, wordt gespecificeerd in het antwoord:

HttpRequest request = HttpRequest.newBuilder () .uri (nieuwe URI ("// postman-echo.com/get")) .version (HttpClient.Version.HTTP_2) .GET () .build (); HttpResponse antwoord = HttpClient.newHttpClient () .send (verzoek, HttpResponse.BodyHandler.asString ()); assertThat (response.version (), equalTo (HttpClient.Version.HTTP_1_1));

8. Java 11 Http-client

De belangrijkste verandering in Java 11 was de standaardisatie van HTTP-client-API die HTTP / 2 en Web Socket implementeert. Het heeft tot doel de erfenis te vervangen HttpUrlConnection klasse die aanwezig is in de JDK sinds de allereerste jaren van Java.

De wijziging is geïmplementeerd als onderdeel van JEP 321.

8.1. Belangrijke wijzigingen als onderdeel van JEP 321

  1. De geïncubeerde HTTP API van Java 9 is nu officieel opgenomen in de Java SE API. De nieuwe HTTP-API's zijn te vinden in java.net.HTTP. *
  2. De nieuwere versie van het HTTP-protocol is ontworpen om de algehele prestaties van het verzenden van verzoeken door een client en het ontvangen van antwoorden van de server te verbeteren. Dit wordt bereikt door een aantal veranderingen door te voeren, zoals stream-multiplexing, header-compressie en push-beloften.
  3. Vanaf Java 11, de API is nu volledig asynchroon (de vorige HTTP / 1.1-implementatie blokkeerde). Asynchrone oproepen worden geïmplementeerd met CompletableFuture.De CompletableFuture implementatie zorgt ervoor dat elke fase wordt toegepast zodra de vorige is voltooid, dus deze hele stroom is asynchroon.
  4. De nieuwe HTTP-client-API biedt een standaardmanier om HTTP-netwerkbewerkingen uit te voeren met ondersteuning voor moderne webfuncties zoals HTTP / 2, zonder de noodzaak om afhankelijkheden van derden toe te voegen.
  5. De nieuwe API's bieden native ondersteuning voor HTTP 1.1 / 2 WebSocket. De kernklassen en interface die de kernfunctionaliteit bieden, zijn onder meer:
  • De HttpClient-klasse, java.net.http.HttpClient
  • De HttpRequest klasse, java.net.http.HttpRequest
  • De HttpResponse koppel, java.net.http.HttpResponse
  • De WebSocket koppel, java.net.http.WebSocket

8.2. Problemen met de Pre Java 11 HTTP-client

Het bestaan HttpURLConnection API en de implementatie ervan hadden tal van problemen:

  • URLConnection API is ontworpen met meerdere protocollen die nu niet meer werken (FTP, gopher, etc.).
  • De API dateert van vóór HTTP / 1.1 en is te abstract.
  • Het werkt alleen in de blokkeermodus (d.w.z. één thread per verzoek / reactie).
  • Het is erg moeilijk te onderhouden.

9. Veranderingen in Http Client met Java 11

9.1. Introductie van statische fabriekslessen

Nieuwe statische fabrieksklassen BodyPublishers, BodyAbonnees, en BodyHandlers worden geïntroduceerd die bestaande implementaties van BodyPublisher, BodySubscriber en BodyHandler.

Deze worden gebruikt om nuttige algemene taken uit te voeren, zoals het behandelen van de antwoordtekst als een tekenreeks of het streamen van de hoofdtekst naar een bestand.

Voor b.v. in Pre Java 11 moesten we zoiets als dit doen:

HttpResponse response = client.send (verzoek, HttpResponse.BodyHandler.asString ());

Wat we nu kunnen vereenvoudigen als:

HttpResponse response = client.send (verzoek, BodyHandlers.ofString ());

Ook is de naam van statische methoden gestandaardiseerd voor meer duidelijkheid.

Voor b.v. methoden namen zoals fromXxx worden gebruikt wanneer we ze gebruiken als adapters of namen zoals ofXxx wanneer we vooraf gedefinieerde handlers / abonnees maken.

9.2. Vloeiende methoden voor gewone lichaamstypes

Handige fabrieksmethoden voor gecreëerde uitgevers en handlers voor het omgaan met veelvoorkomende lichaamstypes zijn geïntroduceerd.

Voor b.v. we hebben onderstaande vloeiende methoden voor het maken van uitgevers op basis van bytes, bestanden en strings:

BodyPublishers.ofByteArray BodyPublishers.ofFile BodyPublishers.ofString

Evenzo kunnen we voor het maken van handlers van deze veel voorkomende lichaamstypes gebruiken:

BodyHandlers.ofByteArray BodyHandlers.ofString BodyHandlers.ofFile

9.3. Andere API-wijzigingen

1. Met deze nieuwe API gaan we gebruiken BodyHandlers.discarding () en BodyHandlers.replacing (waarde) in plaats van weggooien (objectvervanging):

HttpResponse response1 = HttpClient.newHttpClient () .send (verzoek, BodyHandlers.discarding ());
HttpResponse response1 = HttpClient.newHttpClient () .send (verzoek, BodyHandlers.replacing (waarde));

2. Nieuwe methode ofLines () in BodyHandlers wordt toegevoegd om het streamen van de antwoordtekst af te handelen als een stroom lijnen.

3. fromLineSubscriber methode is toegevoegd in BodyHandlers klasse die kan worden gebruikt als een adapter tussen een BodySubscriber en een op tekst gebaseerd Flow. Abonnee die tekst regel voor regel parseert.

4. Een nieuw toegevoegd BodySubscriber.mapping in BodySubscribers klasse die kan worden gebruikt voor het toewijzen van het ene antwoordbody-type naar het andere door de gegeven functie toe te passen op het body-object.

5. In HttpClient.Redirect, opsommingsconstanten SAME_PROTOCOL en VEILIG beleid worden vervangen door een nieuwe opsomming NORMAAL.

10. Push-beloftes afhandelen in HTTP / 2

Nieuwe HTTP-client ondersteunt push-beloften PushPromiseHandler koppel.

Het stelt de server in staat om inhoud naar de client te “pushen”, terwijl de primaire bron wordt opgevraagd, waardoor er meer roundtrips worden bespaard en als resultaat de prestaties bij het renderen van pagina's worden verbeterd.

Het is echt de multiplexfunctie van HTTP / 2 waardoor we het bundelen van bronnen kunnen vergeten. Voor elke bron stuurt de server een speciaal verzoek, een zogenaamde pushbelofte naar de klant.

Ontvangen push-beloften, indien van toepassing, worden afgehandeld door de gegeven PushPromiseHandler. Een niet-gewaardeerde PushPromiseHnadler wijst alle pushbeloftes af.

De HttpClient heeft een overbelast sendAsync methode die ons in staat stelt om met dergelijke beloften om te gaan, zoals in onderstaand voorbeeld wordt getoond.

Laten we eerst een PushPromiseHandler:

privé statische PushPromiseHandler pushPromiseHandler () {return (HttpRequest initatingRequest, HttpRequest pushPromiseRequest, Functie> acceptor) -> {acceptor.apply (BodyHandlers.ofString ()) .thenAccept (resp -> {System.out.println ("Pushed response:" + resp.uri () + ", headers:" + resp.headers ());}); System.out.println ("Promise request:" + pushPromiseRequest.uri ()); System.out.println ("Promise request:" + pushPromiseRequest.headers ()); }; }

Laten we vervolgens gebruiken sendAsync methode om met deze pushbelofte om te gaan:

httpClient.sendAsync (pageRequest, BodyHandlers.ofString (), pushPromiseHandler ()) .thenAccept (pageResponse -> {System.out.println ("Paginaresponsstatuscode:" + pageResponse.statusCode ()); System.out.println ( "Paginareactie headers:" + pageResponse.headers ()); String responseBody = pageResponse.body (); System.out.println (responseBody);}) .join (); 

11. Conclusie

In dit artikel hebben we Java 9's onderzocht HttpClient API die veel flexibiliteit en krachtige functies biedt. De volledige code die wordt gebruikt voor de HttpClient API van Java 9 is beschikbaar op GitHub.

We hebben ook de nieuwe verandering in Java 11 HttpClient onderzocht, die de incuberende HttpClient die in Java 9 werd geïntroduceerd, gestandaardiseerd met krachtigere wijzigingen. De codefragmenten die worden gebruikt voor Java 11 Http Client zijn ook beschikbaar via Github.

Opmerking: in de voorbeelden hebben we voorbeeld-REST-eindpunten gebruikt die worden geleverd door //postman-echo.com.