Asynkron HTTP med async-http-klient i Java

1. Oversikt

AsyncHttpClient (AHC) er et bibliotek bygget på toppen av Netty, med det formål å enkelt utføre HTTP-forespørsler og behandle svar asynkront.

I denne artikkelen vil vi presentere hvordan du konfigurerer og bruker HTTP-klienten, hvordan du utfører en forespørsel og behandler svaret ved hjelp av AHC.

2. Oppsett

Den siste versjonen av biblioteket finner du i Maven-arkivet. Vi bør være forsiktige med å bruke avhengigheten av gruppe-ID-en org.asynchttpclient og ikke den med com.ning:

 org.asynchttpclient async-http-client 2.2.0 

3. HTTP-klientkonfigurasjon

Den mest enkle metoden for å skaffe deg HTTP-klienten er ved å bruke Dsl klasse. Det statiske asyncHttpClient () metoden returnerer en AsyncHttpClient gjenstand:

AsyncHttpClient-klient = Dsl.asyncHttpClient ();

Hvis vi trenger en tilpasset konfigurasjon av HTTP-klienten, kan vi bygge AsyncHttpClient objekt ved hjelp av byggmesteren DefaultAsyncHttpClientConfig.Builder:

DefaultAsyncHttpClientConfig.Builder clientBuilder = Dsl.config ()

Dette gir muligheten til å konfigurere tidsavbrudd, en proxy-server, HTTP-sertifikater og mange flere:

DefaultAsyncHttpClientConfig.Builder clientBuilder = Dsl.config () .setConnectTimeout (500). SetProxyServer (ny ProxyServer (...)); AsyncHttpClient-klient = Dsl.asyncHttpClient (clientBuilder);

Når vi har konfigurert og fått en forekomst av HTTP-klienten, kan vi gjenbruke den på tvers av applikasjonen. Vi trenger ikke lage en forekomst for hver forespørsel, fordi det internt oppretter nye tråder og tilkoblingsbassenger, noe som vil føre til ytelsesproblemer.

Det er også viktig å merke seg det når vi er ferdig med å bruke klienten, bør vi ringe til Lukk() metode for å forhindre minnelekkasjer eller hengende ressurser.

4. Opprette en HTTP-forespørsel

Det er to metoder der vi kan definere en HTTP-forespørsel ved hjelp av AHC:

  • bundet
  • ubundet

Det er ingen stor forskjell mellom de to forespørselstypene når det gjelder ytelse. De representerer bare to separate APIer vi kan bruke til å definere en forespørsel. En bundet forespørsel er knyttet til HTTP-klienten den ble opprettet fra, og vil som standard bruke konfigurasjonen til den spesifikke klienten hvis ikke annet er spesifisert.

For eksempel når du oppretter en bundet forespørsel disableUrlEncoding flagg leses fra HTTP-klientkonfigurasjonen, mens dette for en ubundet forespørsel som standard er satt til false. Dette er nyttig fordi klientkonfigurasjonen kan endres uten å kompilere hele applikasjonen på nytt ved å bruke systemegenskaper som er sendt som VM-argumenter:

java -jar -Dorg.asynchttpclient.disableUrlEncodingForBoundRequests = true

En komplett liste over eiendommer finner du ahc-default.properties fil.

4.1. Bundet forespørsel

For å lage en bundet forespørsel bruker vi hjelpemetodene fra klassen AsyncHttpClient som begynner med prefikset "forberede". Vi kan også bruke forberede forespørsel () metode som mottar en allerede opprettet Be om gjenstand.

For eksempel prepareGet () metoden vil opprette en HTTP GET-forespørsel:

BoundRequestBuilder getRequest = client.prepareGet ("// www.baeldung.com");

4.2. Ubundet forespørsel

En ubundet forespørsel kan opprettes ved hjelp av RequestBuilder klasse:

Be om getRequest = ny RequestBuilder (HttpConstants.Methods.GET) .setUrl ("// www.baeldung.com") .build ();

eller ved å bruke Dsl hjelperklasse, som faktisk bruker RequestBuilder for å konfigurere HTTP-metoden og URL-en til forespørselen:

Be om getRequest = Dsl.get ("// www.baeldung.com"). Build ()

5. Utføre HTTP-forespørsler

Navnet på biblioteket gir oss et hint om hvordan forespørslene kan utføres. AHC har støtte for både synkrone og asynkrone forespørsler.

Å utføre forespørselen avhenger av typen. Når du bruker en bundet forespørsel bruker vi henrette() metoden fra BoundRequestBuilder klasse og når vi har en ubundet forespørsel, vi utfører den ved hjelp av en av implementeringene av executeRequest () -metoden fra AsyncHttpClient grensesnitt.

5.1. Synkront

Biblioteket var designet for å være asynkront, men når det er nødvendig kan vi simulere synkrone anrop ved å blokkere på Framtid gjenstand. Både henrette() og executeRequest () metoder returnerer a ListenableFuture gjenstand. Denne klassen utvider Java Framtid grensesnitt, og arver dermed få() metode, som kan brukes til å blokkere den gjeldende tråden til HTTP-forespørselen er fullført og returnerer et svar:

Fremtidig responsFuture = boundGetRequest.execute (); responsFuture.get ();
Fremtidig responsFuture = client.executeRequest (ubundetRequest); responsFuture.get ();

Å bruke synkrone anrop er nyttig når du prøver å feilsøke deler av koden vår, men det anbefales ikke å brukes i et produksjonsmiljø der asynkrone kjøringer fører til bedre ytelse og gjennomstrømning.

5.2. Asynkront

Når vi snakker om asynkrone henrettelser, snakker vi også om lyttere som behandler resultatene. AHC-biblioteket har 3 typer lyttere som kan brukes til asynkrone HTTP-samtaler:

  • AsyncHandler
  • AsyncCompletionHandler
  • ListenableFuture lyttere

De AsyncHandler lytter gir muligheten til å kontrollere og behandle HTTP-samtalen før den er fullført. Å bruke den kan håndtere en rekke hendelser relatert til HTTP-samtalen:

request.execute (ny AsyncHandler () {@Override public State onStatusReceived (HttpResponseStatus responseStatus) kaster unntak {return null;} @ Override public State onHeadersReceived (HttpHeaders headers) kaster unntak {return null;} @Override public State onBodyPartBodyPart kaster Unntak {return null;} @ Override public void onThrowable (Throwable t) {} @ Override public Object onCompleted () kaster Unntak {return null;}});

De Stat enum lar oss kontrollere behandlingen av HTTP-forespørselen. Ved å komme tilbake State.ABORT vi kan stoppe behandlingen på et bestemt tidspunkt og ved å bruke Stat. FORTSETT vi lar behandlingen fullføre.

Det er viktig å nevne at AsyncHandler er ikke trådsikker og bør ikke brukes på nytt når du utfører samtidige forespørsler.

AsyncCompletionHandler arver alle metodene fra AsyncHandler grensesnitt og legger til onCompleted (svar) hjelpermetode for å håndtere samtalen. Alle de andre lyttermetodene overstyres for å returnere Stat.FORTSETT, og dermed blir koden mer lesbar:

request.execute (ny AsyncCompletionHandler () {@Override public Object onCompleted (Response response) kaster Unntak {returrespons;}});

De ListenableFuture grensesnitt kan vi legge til lyttere som vil kjøre når HTTP-samtalen er fullført.

La oss også utføre koden fra lytterne - ved å bruke en annen trådgruppe:

ListenableFuture listenableFuture = klient .executeRequest (ubundetRequest); listenableFuture.addListener (() -> {Response response = listenableFuture.get (); LOG.debug (response.getStatusCode ());}, Executors.newCachedThreadPool ());

Dessuten er muligheten for å legge til lyttere, den ListenableFuture grensesnitt lar oss transformere Framtid svar på en Fullførbar fremtid.

7. Konklusjon

AHC er et veldig kraftig bibliotek, med mange interessante funksjoner. Det gir en veldig enkel måte å konfigurere en HTTP-klient og muligheten til å utføre både synkron og asynkron forespørsel.

Som alltid er kildekoden for artikkelen tilgjengelig på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found