Istraživanje novog HTTP klijenta u Javi

1. Uvod

U ovom uputstvu istražit ćemo novu inkubaciju Java 9 HttpClient.

Do nedavno je Java pružala samo HttpURLConnection API - koji je nizak i nije poznat po tome što je bogat značajkamaiuser-friendly.

Stoga su se često koristile neke široko korištene biblioteke trećih strana - poput Apache HttpClient, Jetty i Spring's RestTemplate.

2. Početno postavljanje

Modul HTTP klijenta isporučuje se u paketu kao modul inkubatora u JDK 9 i podržava HTTP / 2 s povratnom kompatibilnošću i dalje olakšavajući HTTP / 1.1.

Da bismo ga koristili, moramo definirati naš modul pomoću a module-info.java datoteka koja također ukazuje na potreban modul za pokretanje naše aplikacije:

modul com.baeldung.java9.httpclient {zahtijeva jdk.incubator.httpclient; }

3. Pregled API-ja HTTP klijenta

Za razliku od HttpURLConnection, HTTP klijent pruža sinkrone i asinkrone mehanizme zahtjeva.

API se sastoji od 3 osnovne klase:

  • HttpRequestpredstavlja zahtjev za slanje putem HttpClient
  • HttpClientponaša se kao spremnik za informacije o konfiguraciji zajedničke za više zahtjeva
  • HttpResponsepredstavlja rezultat HttpRequest poziv

Svakog ćemo detaljnije ispitati u sljedećim odjeljcima. Prvo se usredotočimo na zahtjev.

4. HttpRequest

HttpRequest, kao ime sugerira, je objekt koji predstavlja zahtjev koji želimo poslati. Nove instance mogu se stvoriti pomoću HttpRequest.Builder.

Do njega možemo doći pozivom HttpRequest.newBuilder (). Graditelj klasa nudi hrpu metoda koje možemo koristiti za konfiguriranje našeg zahtjeva.

Obradit ćemo najvažnije.

4.1. Postavljanje URI

Prva stvar koju moramo napraviti prilikom stvaranja zahtjeva je pružanje URL-a.

To možemo učiniti na dva načina - upotrebom konstruktora za Graditelj s URI parametar ili metodom pozivanja uri (URI) na Graditelj primjer:

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

Posljednje što moramo konfigurirati za stvaranje osnovnog zahtjeva je HTTP metoda.

4.2. Određivanje HTTP metode

HTTP metodu koju će koristiti naš zahtjev možemo definirati pozivanjem jedne od metoda iz Graditelj:

  • DOBITI()
  • POST (BodyProcessor tijelo)
  • PUT (BodyProcessor tijelo)
  • IZBRIŠI (BodyProcessor tijelo)

Pokrivat ćemo BodyProcessor detaljno, kasnije. Ajmo sada samo stvarati vrlo jednostavan primjer zahtjeva GET:

Zahtjev za HttpRequest = HttpRequest.newBuilder () .uri (novi URI ("// postman-echo.com/get")) .GET () .build ();

Ovaj zahtjev ima sve parametre koje traži HttpClient. Međutim, ponekad svom zahtjevu moramo dodati dodatne parametre; evo nekih važnih:

  • inačici HTTP protokola
  • zaglavlja
  • timeout

4.3. Postavljanje verzije HTTP protokola

API u potpunosti koristi HTTP / 2 protokol i koristi ga prema zadanim postavkama, ali možemo definirati koju verziju protokola želimo koristiti.

Zahtjev za HttpRequest = HttpRequest.newBuilder () .uri (novi URI ("// postman-echo.com/get")) .verzija (HttpClient.Version.HTTP_2) .GET () .build ();

Ovdje je važno napomenuti da će se klijent vratiti na npr. HTTP / 1.1 ako HTTP / 2 nije podržan.

4.4. Postavljanje zaglavlja

U slučaju da svom zahtjevu želimo dodati dodatna zaglavlja, možemo se koristiti navedenim metodama graditelja.

To možemo učiniti na jedan od dva načina:

  • prosljeđujući sva zaglavlja kao parove ključ / vrijednost zaglavlja () metodom ili po
  • koristeći Zaglavlje() metoda za pojedinačno zaglavlje vrijednost-vrijednost:
Zahtjev za HttpRequest = HttpRequest.newBuilder () .uri (novi URI ("// postman-echo.com/get")) .headers ("key1", "value1", "key2", "value2") .GET () .izgraditi(); HttpRequest request2 = HttpRequest.newBuilder () .uri (novi URI ("// postman-echo.com/get")) .header ("key1", "value1") .header ("key2", "value2"). GET () .build (); 

Posljednja korisna metoda koju možemo koristiti za prilagodbu našeg zahtjeva je vremensko ograničenje ().

4.5. Postavljanje vremenskog ograničenja

Definirajmo sada koliko vremena želimo čekati na odgovor.

Ako postavljeno vrijeme istekne, a HttpTimeoutException bit će bačen; zadani timeout je postavljen na beskonačnost.

Vrijeme se može postaviti pomoću Trajanje objekt - pozivanjem metode pauza() na instanci graditelja:

Zahtjev za HttpRequest = HttpRequest.newBuilder () .uri (novi URI ("// postman-echo.com/get")). Timeout (Duration.of (10, SECONDS)) .GET () .build ();

5. Postavljanje tijela zahtjeva

Zahtjevu možemo dodati tijelo pomoću metoda graditelja zahtjeva: POST (BodyProcessor tijelo), PUT (BodyProcessor tijelo) i DELETE (BodyProcessor body).

Novi API nudi niz BodyProcessor implementacije izvan okvira koje pojednostavljuju prosljeđivanje tijela zahtjeva:

  • StringProcessor (čita tijelo iz a Niz, stvoreno sa HttpRequest.BodyProcessor.fromString)
  • InputStreamProcessor (čita tijelo iz InputStream, stvoreno sa HttpRequest.BodyProcessor.fromInputStream)
  • ByteArrayProcessor (čita tijelo iz bajt polja, stvorene sa HttpRequest.BodyProcessor.fromByteArray)
  • FileProcessor (čita tijelo iz datoteke na zadanom putu, stvoreno sa HttpRequest.BodyProcessor.fromFile)

U slučaju da nam ne treba tijelo, možemo jednostavno proći kroz HttpRequest.noBody ():

Zahtjev za HttpRequest = HttpRequest.newBuilder () .uri (novi URI ("// postman-echo.com/post")) .POST (HttpRequest.noBody ()) .build ();

5.1. StringBodyProcessor

Postavljanje tijela zahtjeva s bilo kojim BodyProcessor implementacija je vrlo jednostavna i intuitivna.

Na primjer, ako želimo proći jednostavan Niz kao tijelo možemo koristiti StringBodyProcessor.

Kao što smo već spomenuli, ovaj se objekt može stvoriti tvorničkom metodom fromString (); potrebno je samo a Niz objekt kao argument i od njega stvara tijelo:

Zahtjev za HttpRequest = HttpRequest.newBuilder () .uri (novi URI ("// postman-echo.com/post")) .headers ("Content-Type", "text / plain; charset = UTF-8") .POST (HttpRequest.BodyProcessor.fromString ("Tijelo zahtjeva uzorka")) .build (); 

5.2. InputStreamBodyProcessor

Da biste to učinili, InputStream mora se proći kao a Dobavljač (da njegovo stvaranje bude lijeno), pa je malo drugačije od gore opisanog StringBodyProcessor.

Međutim, ovo je također vrlo jednostavno:

byte [] sampleData = "Tijelo zahtjeva uzorka" .getBytes (); HttpRequest zahtjev = HttpRequest.newBuilder () .uri (novi URI ("// postman-echo.com/post")) .headers ("Content-Type", "text / plain; charset = UTF-8") .POST (HttpRequest.BodyProcessor .fromInputStream (() -> novi ByteArrayInputStream (sampleData))) .build (); 

Primijetite kako smo koristili jednostavan ByteArrayInputStream ovdje; to, naravno, može biti bilo koje InputStream provedba.

5.3. ByteArrayProcessor

Možemo i koristiti ByteArrayProcessor i kao parametar proslijedite niz bajtova:

byte [] sampleData = "Tijelo zahtjeva uzorka" .getBytes (); HttpRequest zahtjev = HttpRequest.newBuilder () .uri (novi URI ("// postman-echo.com/post")) .headers ("Content-Type", "text / plain; charset = UTF-8") .POST (HttpRequest.BodyProcessor.fromByteArray (sampleData)) .build ();

5.4. FileProcessor

Za rad s datotekom možemo iskoristiti ponuđenu datoteku FileProcessor; njegova tvornička metoda uzima put do datoteke kao parametar i stvara tijelo od sadržaja:

Zahtjev za HttpRequest = HttpRequest.newBuilder () .uri (novi 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 ();

Pokrili smo kako stvarati HttpRequest i kako u njemu postaviti dodatne parametre.

Sada je vrijeme da to malo dublje pogledamo HttpClient klase koja je odgovorna za slanje zahtjeva i primanje odgovora.

6. HttpClient

Svi se zahtjevi šalju pomoću HttpClient koji se mogu instancirati pomoću HttpClient.newBuilder () metodom ili pozivom HttpClient.newHttpClient ().

Pruža puno korisnih i samoopisnih metoda koje možemo koristiti za obradu našeg zahtjeva / odgovora.

Pokrijmo neke od njih ovdje.

6.1. Postavljanje proxyja

Možemo definirati proxy za vezu. Samo nazovi proxy () metoda na a Graditelj primjer:

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

U našem smo primjeru koristili zadani sistemski proxy.

6.2. Postavljanje politike preusmjeravanja

Ponekad se stranica kojoj želimo pristupiti premjestila na drugu adresu.

U tom ćemo slučaju primiti HTTP statusni kôd 3xx, obično s informacijama o novom URI-ju. HttpClient može automatski preusmjeriti zahtjev na novi URI ako postavimo odgovarajuću politiku preusmjeravanja.

Možemo to učiniti s followRedirects () metoda na Graditelj:

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

Sve su politike definirane i opisane u enum HttpClient.Preusmjeravanje.

6.3. Postavljanje Autentifikator za vezu

An Autentifikator je objekt koji ugovara vjerodajnice (HTTP provjera autentičnosti) za vezu.

Pruža različite sheme provjere autentičnosti (poput npr. Osnovne ili digest provjere autentičnosti). U većini slučajeva za autentifikaciju su potrebna korisničko ime i lozinka za povezivanje s poslužiteljem.

Možemo koristiti PasswordAuthentication klasa koja je samo nositelj ovih vrijednosti:

HttpResponse response = HttpClient.newBuilder () .authenticator (new Authenticator () {@Override protected PasswordAuthentication getPasswordAuthentication () {return new PasswordAuthentication ("username", "password" .toCharArray ());}}). (zahtjev, HttpResponse.BodyHandler.asString ());

U gornjem primjeru smo proslijedili vrijednosti korisničkog imena i lozinke kao otvoreni tekst; naravno, u proizvodnom scenariju to će morati biti drugačije.

Imajte na umu da svaki zahtjev ne smije koristiti isto korisničko ime i lozinku. The Autentifikator razred pruža niz getXXX (npr. getRequestingSite ()) metode pomoću kojih se može saznati koje vrijednosti treba pružiti.

Sada ćemo istražiti jednu od najkorisnijih značajki nove HttpClient - asinkroni pozivi poslužitelju.

6.4. Pošaljite zahtjeve - Sinkronizacija u odnosu na Async

Novi HttpClient pruža dvije mogućnosti za slanje zahtjeva na poslužitelj:

  • poslati(…) - sinkrono (blokira dok odgovor ne stigne)
  • sendAsync (…) - asinkrono (ne čeka odgovor, ne blokira)

Do sada je poslati(...) metoda prirodno čeka odgovor:

HttpResponse odgovor = HttpClient.newBuilder () .build () .send (zahtjev, HttpResponse.BodyHandler.asString ()); 

Ovaj poziv vraća znak HttpResponse objekta, a sigurni smo da će se sljedeća uputa iz našeg tijeka aplikacije izvršiti samo kad je odgovor već ovdje.

Međutim, ima puno nedostataka, posebno kada obrađujemo velike količine podataka.

Dakle, sada možemo koristiti sendAsync (...) metoda - koja se vraća CompletableFeatureza obradu zahtjeva asinkrono:

CompletableFuture odgovor = HttpClient.newBuilder () .build () .sendAsync (zahtjev, HttpResponse.BodyHandler.asString ());

Novi API također se može nositi s više odgovora i strujati tijela zahtjeva i odgovora:

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

6.5. Postavljanje Izvršitelj za asinkrone pozive

Također možemo definirati i Izvršitelj koji pruža niti koje će se koristiti u asinkronim pozivima.

Na ovaj način možemo, na primjer, ograničiti broj niti koje se koriste za obradu zahtjeva:

ExecutorService executorService = Izvršitelji.newFixedThreadPool (2); CompletableFuture response1 = HttpClient.newBuilder () .executor (executorService) .build () .sendAsync (zahtjev, HttpResponse.BodyHandler.asString ()); CompletableFuture response2 = HttpClient.newBuilder () .executor (executorService) .build () .sendAsync (zahtjev, HttpResponse.BodyHandler.asString ());

Prema zadanim postavkama HttpClient koristi izvršitelj java.util.concurrent.Executors.newCachedThreadPool ().

6.6. Utvrđivanje a Upravitelj kolačića

S novim API-jem i graditeljem jednostavno je postaviti a Upravitelj kolačića za našu vezu. Možemo se koristiti graditeljskom metodom cookieManager (CookieManager cookieManager) za definiranje specifičnih za klijenta Upravitelj kolačića.

Idemo, na primjer, definirati Upravitelj kolačića što uopće ne dopušta prihvaćanje kolačića:

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

U slučaju da naša Upravitelj kolačića omogućuje pohranu kolačića, možemo im pristupiti provjerom Upravitelj kolačića od našeg HttpClient:

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

Sada se usredotočimo na posljednju klasu iz Http API-ja - HttpResponse.

7. HttpResponse Objekt

The HttpResponse klasa predstavlja odgovor poslužitelja. Pruža brojne korisne metode - ali dvije najvažnije su:

  • statusCode () - vraća statusni kod (vrsta int) za odgovor (HttpURLConnection razred sadrži moguće vrijednosti)
  • tijelo() - vraća tijelo na odgovor (vrsta povrata ovisi o odgovoru BodyHandler parametar proslijeđen u poslati() metoda)

Objekt odgovora ima drugu korisnu metodu koju ćemo pokriti uri (), zaglavlja (), prikolice () i verzija().

7.1. URI objekta odgovora

Metoda uri () na objekt odgovora vraća URI s kojeg smo dobili odgovor.

Ponekad može biti drugačije od URI u objektu zahtjeva, jer može doći do preusmjeravanja:

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

7.2. Zaglavlja iz odgovora

Zaglavlja iz odgovora možemo dobiti pozivanjem metode zaglavlja () na objektu odgovora:

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

Vraća se HttpHeaders objekt kao povratni tip. Ovo je novi tip definiran u jdk.inkubator.http paket koji predstavlja pogled samo za čitanje HTTP zaglavlja.

Ima nekoliko korisnih metoda koje pojednostavljuju traženje vrijednosti zaglavlja.

7.3. Nabavite prikolice od Responsea

HTTP odgovor može sadržavati dodatna zaglavlja koja su uključena nakon sadržaja odgovora. Ta se zaglavlja nazivaju zaglavljima prikolica.

Možemo ih dobiti pozivom prikolice () na HttpResponse:

HttpResponse odgovor = HttpClient.newHttpClient () .send (zahtjev, HttpResponse.BodyHandler.asString ()); CompletableFuture prikolice = response.trailers (); 

Imajte na umu da prikolice () metoda se vraća CompletableFuture objekt.

7.4. Verzija odgovora

Metoda verzija() definira koja je verzija HTTP protokola korištena za razgovor sa poslužiteljem.

Zapamtite, čak i ako definiramo da želimo koristiti HTTP / 2, poslužitelj može odgovoriti putem HTTP / 1.1.

Verzija u kojoj je poslužitelj odgovorio navedena je u odgovoru:

Zahtjev za HttpRequest = HttpRequest.newBuilder () .uri (novi URI ("// postman-echo.com/get")) .verzija (HttpClient.Version.HTTP_2) .GET () .build (); HttpResponse odgovor = HttpClient.newHttpClient () .send (zahtjev, HttpResponse.BodyHandler.asString ()); assertThat (response.version (), jednakTo (HttpClient.Version.HTTP_1_1));

8. Java 11 HTTP klijent

Glavna promjena u Javi 11 bila je standardizacija API HTTP klijenta koji implementira HTTP / 2 i Web Socket. Cilj mu je zamijeniti naslijeđe HttpUrlConnection klase koja je prisutna u JDK od vrlo ranih godina Jave.

Promjena je provedena kao dio JEP 321.

8.1. Glavne promjene kao dio JEP-a 321

  1. Inkubirani HTTP API iz Jave 9 sada je službeno ugrađen u Java SE API. Nove HTTP API-je možete pronaći u java.net.HTTP. *
  2. Novija verzija HTTP protokola namijenjena je poboljšanju ukupne izvedbe slanja zahtjeva klijenta i primanja odgovora s poslužitelja. To se postiže uvođenjem brojnih promjena poput multipleksiranja toka, kompresije zaglavlja i push obećanja.
  3. Od Jave 11, API je sada potpuno asinkron (prethodna implementacija HTTP / 1.1 blokirala je). Asinkroni pozivi provode se pomoću CompletableFuture.The CompletableFuture implementacija se brine za primjenu svake faze nakon što prethodna završi, tako da je cijeli taj tijek asinkron.
  4. Novi API HTTP klijenta pruža standardni način izvođenja HTTP mrežnih operacija s podrškom za moderne web značajke kao što je HTTP / 2, bez potrebe za dodavanjem nezavisnih ovisnosti.
  5. Novi API-ji pružaju izvornu podršku za HTTP 1.1 / 2 WebSocket. Osnovne klase i sučelje koje pružaju osnovnu funkcionalnost uključuju:
  • The Klasa HttpClient, java.net.http.HttpClient
  • The HttpRequest razred, java.net.http.HttpRequest
  • The HttpResponse sučelje, java.net.http.HttpResponse
  • The WebSocket sučelje, java.net.http.WebSocket

8.2. Problemi s Pre Java 11 HTTP klijentom

Postojeće HttpURLConnection API i njegova implementacija imali su brojne probleme:

  • API URLConnection dizajniran je s više protokola koji sada više ne funkcioniraju (FTP, gopher itd.).
  • API prethodi HTTP / 1.1 i previše je apstraktan.
  • Radi samo u načinu blokiranja (tj. Jedna nit po zahtjevu / odgovoru).
  • To je vrlo teško održavati.

9. Promjene u HTTP klijentu s Javom 11

9.1. Uvođenje statičkih tvorničkih klasa

Nove statičke tvorničke klase BodyPublishers, BodySubscribers, i BodyHandlers uvode se koji uključuju postojeće implementacije BodyPublisher, BodySubscriber i BodyHandler.

Koriste se za obavljanje korisnih uobičajenih zadataka, poput rukovanja tijelom odgovora kao niza ili pretakanja tijela u datoteku.

Jer npr. u Pre Java 11 morali smo učiniti nešto poput ovoga:

HttpResponse odgovor = client.send (zahtjev, HttpResponse.BodyHandler.asString ());

Što sada možemo pojednostaviti kao:

HttpResponse odgovor = client.send (zahtjev, BodyHandlers.ofString ());

Također, naziv statičkih metoda standardiziran je radi veće jasnoće.

Jer npr. metode imena poput odXxx se koriste kada ih koristimo kao adaptere ili nazive poput odXxx kada stvaramo unaprijed definirane rukovatelje / pretplatnike.

9.2. Tekuće metode za uobičajene tipove tijela

Uvedene su prikladne tvorničke metode za stvorene izdavače i rukovatelje za rukovanje uobičajenim tipovima tijela.

Jer npr. dolje imamo tečne metode za stvaranje izdavača iz bajtova, datoteka i nizova:

BodyPublishers.ofByteArray BodyPublishers.ofFile BodyPublishers.ofString

Slično tome, za stvaranje rukovatelja od ovih uobičajenih tipova tijela možemo koristiti:

BodyHandlers.ofByteArray BodyHandlers.ofString BodyHandlers.ofFile

9.3. Ostale izmjene API-ja

1. Pomoću ovog novog API-ja BodyHandlers.discarding () i BodyHandlers.replacing (vrijednost) umjesto odbaci (zamjena predmeta):

HttpResponse response1 = HttpClient.newHttpClient () .send (zahtjev, BodyHandlers.discarding ());
HttpResponse response1 = HttpClient.newHttpClient () .send (zahtjev, BodyHandlers.replacing (vrijednost));

2. Nova metoda ofLines () u BodyHandlers dodan je za rukovanje strujanjem tijela odgovora kao tok linija.

3. fromLineSubscriber metoda dodana je u BodyHandlers klase koja se može koristiti kao adapter između a BodySubscriber i na temelju teksta Flow.Pretplatnik koja raščlanjuje tekst redak po redak.

4. Dodan novi BodySubscriber.mapping u BodySubscribers klasa koja se može koristiti za preslikavanje iz jednog tipa tijela odgovora u drugi primjenom zadane funkcije na objekt tijela.

5. U HttpClient.Preusmjeravanje, enum konstante ISTI_PROTOKOL i SIGURAN politike zamjenjuju se novim nabrajanjem NORMALAN.

10. Rukovanje push obećanjima u HTTP / 2

Novi Http klijent podržava push obećanja PushPromiseHandler sučelje.

Omogućuje poslužitelju da "potiskuje" sadržaj klijentu dodatne resurse dok zahtijeva primarni resurs, štedi više povratnih putovanja i kao rezultat toga poboljšava izvedbu prikazivanja stranica.

Doista je značajka multipleksiranja HTTP / 2 koja nam omogućuje da zaboravimo na grupiranje resursa. Za svaki resurs poslužitelj klijentu šalje poseban zahtjev, poznat kao push obećanje.

Primljena push-obećanja, ako ih ima, obrađuje dani PushPromiseHandler. Ništa vrijedan PushPromiseHnadler odbija bilo koja push obećanja.

The HttpClient ima preopterećen sendAsync metoda koja nam omogućuje da ispunimo takva obećanja, kao što je prikazano u donjem primjeru.

Prvo stvorimo a PushPromiseHandler:

privatni statički PushPromiseHandler pushPromiseHandler () {return (HttpRequest InitiatingRequest, HttpRequest pushPromiseRequest, Funkcija> acceptor) -> {acceptor.apply (BodyHandlers.ofString ()). thenAccept (resp -> {System.out.println ("Pushed response:" + resp.uri () + ", headers:" + resp.headers ());}); System.out.println ("Zahtjev za obećanje:" + pushPromiseRequest.uri ()); System.out.println ("Zahtjev za obećanje:" + pushPromiseRequest.headers ()); }; }

Dalje, poslužimo se sendAsync metoda za rukovanje ovim push obećanjem:

httpClient.sendAsync (pageRequest, BodyHandlers.ofString (), pushPromiseHandler ()). thenAccept (pageResponse -> {System.out.println ("Šifra statusa odgovora stranice:" + pageResponse.statusCode ()); System.out.println ( "Zaglavlja odgovora stranice:" + pageResponse.headers ()); String responseBody = pageResponse.body (); System.out.println (responseBody);}) .join (); 

11. Zaključak

U ovom smo članku istražili Javu 9 HttpClient API koji pruža veliku fleksibilnost i moćne značajke. Kompletni kod korišten za Java 9-ov HttpClient API dostupan je na GitHub-u.

Također smo istražili novu promjenu u Java 11 HttpClient, koja je standardizirala inkubiranje HttpClienta predstavljenu u Javi 9 s moćnijim promjenama. Isječci koda koji se koriste za Java 11 Http klijent također su dostupni putem Github-a.

Napomena: U primjerima smo koristili uzorke REST krajnjih točaka koje pruža //postman-echo.com.