Asynkron HTTP med async-http-klient i Java

1. Oversigt

AsyncHttpClient (AHC) er et bibliotek, der er bygget oven på Netty, med det formål let at udføre HTTP-anmodninger og behandle svar asynkront.

I denne artikel præsenterer vi, hvordan du konfigurerer og bruger HTTP-klienten, hvordan du udfører en anmodning og behandler svaret ved hjælp af AHC.

2. Opsætning

Den seneste version af biblioteket findes i Maven-arkivet. Vi skal være forsigtige med at bruge afhængigheden af ​​gruppe-id'et org.asynchttpclient og ikke den med com.ning:

 org.asynchttpclient async-http-client 2.2.0 

3. HTTP-klientkonfiguration

Den mest ligefremme metode til at hente HTTP-klienten er ved hjælp af DSL klasse. Det statiske asyncHttpClient () metode returnerer en AsyncHttpClient objekt:

AsyncHttpClient-klient = Dsl.asyncHttpClient ();

Hvis vi har brug for en brugerdefineret konfiguration af HTTP-klienten, kan vi bygge AsyncHttpClient objekt ved hjælp af bygherren DefaultAsyncHttpClientConfig.Builder:

DefaultAsyncHttpClientConfig.Builder clientBuilder = Dsl.config ()

Dette giver mulighed for at konfigurere timeouts, en proxyserver, HTTP-certifikater og mange flere:

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

Når vi har konfigureret og opnået en forekomst af HTTP-klienten, kan vi genbruge den på tværs af applikationen. Vi behøver ikke at oprette en instans for hver anmodning, fordi det internt opretter nye tråde og forbindelsespuljer, hvilket vil føre til problemer med ydeevnen.

Det er også vigtigt at bemærke det når vi er færdige med at bruge klienten, skal vi ringe til tæt() metode til at forhindre hukommelseslækage eller hængende ressourcer.

4. Oprettelse af en HTTP-anmodning

Der er to metoder, hvor vi kan definere en HTTP-anmodning ved hjælp af AHC:

  • bundet
  • ubundet

Der er ingen større forskel mellem de to anmodningstyper med hensyn til ydeevne. De repræsenterer kun to separate API'er, som vi kan bruge til at definere en anmodning. En bundet anmodning er bundet til HTTP-klienten, den blev oprettet fra, og bruger som standard konfigurationen af ​​den specifikke klient, hvis ikke andet er angivet.

For eksempel, når du opretter en bundet anmodning disableUrlEncoding flag læses fra HTTP-klientkonfigurationen, mens dette for en ubundet anmodning som standard er sat til falsk. Dette er nyttigt, fordi klientkonfigurationen kan ændres uden at kompilere hele applikationen igen ved hjælp af systemegenskaber, der er sendt som VM-argumenter:

java -jar -Dorg.asynchttpclient.disableUrlEncodingForBoundRequests = sand

En komplet liste over ejendomme kan findes på ahc-default.properties fil.

4.1. Bundet anmodning

For at oprette en bundet anmodning bruger vi hjælpemetoderne fra klassen AsyncHttpClient der starter med præfikset "forberede". Vi kan også bruge forberede anmodning () metode, der modtager en allerede oprettet Anmodning objekt.

F.eks prepareGet () metoden opretter en HTTP GET-anmodning:

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

4.2. Ubundet anmodning

En ubundet anmodning kan oprettes ved hjælp af RequestBuilder klasse:

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

eller ved hjælp af DSL hjælperklasse, som faktisk bruger RequestBuilder til konfiguration af HTTP-metoden og URL for anmodningen:

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

5. Udførelse af HTTP-anmodninger

Navnet på biblioteket giver os et tip om, hvordan anmodningerne kan udføres. AHC har understøttelse af både synkrone og asynkrone anmodninger.

At udføre anmodningen afhænger af typen. Når du bruger en bundet anmodning bruger vi udføre () metode fra BoundRequestBuilder klasse, og når vi har en ubundet anmodning udfører vi den ved hjælp af en af ​​implementeringerne af metoden executeRequest () fra AsyncHttpClient interface.

5.1. Synkront

Biblioteket var designet til at være asynkront, men efter behov kan vi simulere synkrone opkald ved at blokere på Fremtid objekt. Begge udføre () og executeRequest () metoder returnerer a ListenableFuture objekt. Denne klasse udvider Java Fremtid interface, og arver således få() metode, som kan bruges til at blokere den aktuelle tråd, indtil HTTP-anmodningen er afsluttet og returnerer et svar:

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

Brug af synkrone opkald er nyttigt, når du prøver at fejle dele af vores kode, men det anbefales ikke at blive brugt i et produktionsmiljø, hvor asynkron udførelse fører til bedre ydeevne og gennemstrømning.

5.2. Asynkront

Når vi taler om asynkrone henrettelser, taler vi også om lyttere, der behandler resultaterne. AHC-biblioteket indeholder 3 typer lyttere, der kan bruges til asynkrone HTTP-opkald:

  • AsyncHandler
  • AsyncCompletionHandler
  • ListenableFuture lyttere

Det AsyncHandler lytter giver mulighed for at kontrollere og behandle HTTP-opkaldet, før det er afsluttet. Brug af det kan håndtere en række begivenheder relateret til HTTP-opkaldet:

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

Det Stat enum lader os kontrollere behandlingen af ​​HTTP-anmodningen. Ved at vende tilbage Stat.ABORT vi kan stoppe behandlingen på et bestemt tidspunkt og ved hjælp af Stat. FORTSÆT vi lader behandlingen afslutte.

Det er vigtigt at nævne, at AsyncHandler er ikke trådsikker og bør ikke genbruges, når der udføres samtidige anmodninger.

AsyncCompletionHandler arver alle metoderne fra AsyncHandler interface og tilføjer onCompleted (svar) hjælpermetode til håndtering af opkaldets afslutning. Alle andre lyttermetoder tilsidesættes for at vende tilbage Stat.FORTSÆT, hvilket gør koden mere læselig:

request.execute (ny AsyncCompletionHandler () {@Override public Object onCompleted (Response response) throw Exception {return response;}});

Det ListenableFuture interface lader os tilføje lyttere, der kører, når HTTP-opkaldet er afsluttet.

Lad os også udføre koden fra lytterne - ved hjælp af en anden trådpulje:

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

Desuden er muligheden for at tilføje lyttere, den ListenableFuture interface lader os omdanne Fremtid svar på en Fuldført.

7. Konklusion

AHC er et meget kraftigt bibliotek med mange interessante funktioner. Det giver en meget enkel måde at konfigurere en HTTP-klient og muligheden for at udføre både synkron og asynkron anmodning.

Som altid er kildekoden til artiklen tilgængelig på GitHub.


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