Asynchrone HTTP met asynchrone http-client in Java

1. Overzicht

AsyncHttpClient (AHC) is een bibliotheek die bovenop Netty is gebouwd, met als doel eenvoudig HTTP-verzoeken uit te voeren en reacties asynchroon te verwerken.

In dit artikel laten we zien hoe u de HTTP-client configureert en gebruikt, hoe u een verzoek uitvoert en het antwoord verwerkt met AHC.

2. Installatie

De nieuwste versie van de bibliotheek is te vinden in de Maven-repository. We moeten voorzichtig zijn om de afhankelijkheid met de groeps-id te gebruiken org.asynchttpclient en niet die met com.ning:

 org.asynchttpclient async-http-client 2.2.0 

3. HTTP-clientconfiguratie

De meest eenvoudige methode om de HTTP-client te verkrijgen, is door de DSL klasse. De statische asyncHttpClient () methode retourneert een AsyncHttpClient voorwerp:

AsyncHttpClient-client = Dsl.asyncHttpClient ();

Als we een aangepaste configuratie van de HTTP-client nodig hebben, kunnen we het AsyncHttpClient object met behulp van de builder DefaultAsyncHttpClientConfig.Builder:

DefaultAsyncHttpClientConfig.Builder clientBuilder = Dsl.config ()

Dit biedt de mogelijkheid om time-outs, een proxyserver, HTTP-certificaten en nog veel meer te configureren:

DefaultAsyncHttpClientConfig.Builder clientBuilder = Dsl.config () .setConnectTimeout (500) .setProxyServer (nieuwe ProxyServer (...)); AsyncHttpClient client = Dsl.asyncHttpClient (clientBuilder);

Zodra we hebben geconfigureerd en verkregen een instantie van de HTTP-client kunnen we deze hergebruiken in de hele applicatie. We hoeven niet voor elk verzoek een instantie te maken, omdat het intern nieuwe threads en verbindingspools maakt, wat tot prestatieproblemen zal leiden.

Het is ook belangrijk om dat op te merken zodra we klaar zijn met het gebruik van de client, moeten we bellen dichtbij() methode om geheugenlekken te voorkomen of hangende bronnen.

4. Een HTTP-verzoek maken

Er zijn twee methoden waarmee we een HTTP-verzoek kunnen definiëren met behulp van AHC:

  • gebonden
  • ongebonden

Er is geen groot verschil tussen de twee soorten verzoeken in termen van prestaties. Ze vertegenwoordigen slechts twee afzonderlijke API's die we kunnen gebruiken om een ​​verzoek te definiëren. Een gebonden verzoek is gekoppeld aan de HTTP-client waaruit het is gemaakt en gebruikt standaard de configuratie van die specifieke client, tenzij anders aangegeven.

Als u bijvoorbeeld een gebonden verzoek maakt, wordt het disableUrlEncoding flag wordt gelezen uit de HTTP-clientconfiguratie, terwijl dit voor een niet-gebonden verzoek standaard is ingesteld op false. Dit is handig omdat de clientconfiguratie kan worden gewijzigd zonder de hele applicatie opnieuw te compileren door systeemeigenschappen te gebruiken die als VM-argumenten zijn doorgegeven:

java -jar -Dorg.asynchttpclient.disableUrlEncodingForBoundRequests = true

Een volledige lijst met eigenschappen is te vinden op het ahc-default.properties het dossier.

4.1. Gebonden verzoek

Om een ​​gebonden verzoek te maken, gebruiken we de helper-methoden uit de klasse AsyncHttpClient die beginnen met het voorvoegsel "bereiden". We kunnen ook de voorbereidenRequest () methode die een reeds aangemaakt Verzoek voorwerp.

Bijvoorbeeld de voorbereidenGet () methode zal een HTTP GET-verzoek maken:

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

4.2. Niet-geconsolideerd verzoek

Een ongebonden verzoek kan worden gemaakt met de RequestBuilder klasse:

Request getRequest = nieuwe RequestBuilder (HttpConstants.Methods.GET) .setUrl ("// www.baeldung.com") .build ();

of door de DSL helper-klasse, die feitelijk de RequestBuilder voor het configureren van de HTTP-methode en URL van het verzoek:

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

5. HTTP-verzoeken uitvoeren

De naam van de bibliotheek geeft ons een hint over hoe de verzoeken kunnen worden uitgevoerd. AHC heeft ondersteuning voor zowel synchrone als asynchrone verzoeken.

Het uitvoeren van het verzoek is afhankelijk van het type. Bij gebruik van een gebonden verzoek gebruiken we de uitvoeren () methode van de BoundRequestBuilder klas en als we een ongebonden verzoek zullen we het uitvoeren met behulp van een van de implementaties van de executeRequest () - methode van de AsyncHttpClient koppel.

5.1. Synchroon

De bibliotheek is ontworpen om asynchroon te zijn, maar indien nodig kunnen we synchrone oproepen simuleren door te blokkeren op de Toekomst voorwerp. Beide uitvoeren () en executeRequest () methoden retourneren een Luisterbare toekomst voorwerp. Deze klasse breidt de Java Toekomst interface, waardoor de krijgen() methode, die kan worden gebruikt om de huidige thread te blokkeren totdat het HTTP-verzoek is voltooid en een antwoord retourneert:

Toekomstige responsFuture = boundGetRequest.execute (); responseFuture.get ();
Toekomstige responsFuture = client.executeRequest (unboundRequest); responseFuture.get ();

Het gebruik van synchrone aanroepen is handig bij het debuggen van delen van onze code, maar het wordt niet aanbevolen om te worden gebruikt in een productieomgeving waar asynchrone uitvoeringen leiden tot betere prestaties en doorvoer.

5.2. Asynchroon

Als we het hebben over asynchrone executies, hebben we het ook over luisteraars voor het verwerken van de resultaten. De AHC-bibliotheek biedt 3 soorten luisteraars die kunnen worden gebruikt voor asynchrone HTTP-oproepen:

  • AsyncHandler
  • AsyncCompletionHandler
  • Luisterbare toekomst luisteraars

De AsyncHandler listener biedt de mogelijkheid om de HTTP-oproep te besturen en te verwerken voordat deze is voltooid. Het gebruik ervan kan een reeks gebeurtenissen verwerken die verband houden met de HTTP-oproep:

request.execute (new AsyncHandler () {@Override public State onStatusReceived (HttpResponseStatus responseStatus) gooit uitzondering {return null;} @Override public State onHeadersReceived (HttpHeaders headers) gooit Uitzondering {return null;} @Override public State onBespodyPartonse gooit uitzondering {return null;} @Override public void onThrowable (Throwable t) {} @Override public Object onCompleted () gooit uitzondering {return null;}});

De Staat enum stelt ons in staat de verwerking van het HTTP-verzoek te beheren. Door terug te keren Staat.ABORT we kunnen de verwerking stoppen op een bepaald moment en door gebruik te maken van Staat. DOORGAAN we laten de verwerking eindigen.

Het is belangrijk om te vermelden dat de AsyncHandler is niet thread-safe en mag niet opnieuw worden gebruikt bij het uitvoeren van gelijktijdige verzoeken.

AsyncCompletionHandler erft alle methoden van de AsyncHandler interface en voegt de onCompleted (antwoord) helper-methode voor het afhandelen van het voltooien van de oproep. Alle andere listenermethoden worden overschreven om terug te keren Staat.DOORGAAN, waardoor de code beter leesbaar wordt:

request.execute (new AsyncCompletionHandler () {@Override public Object onCompleted (Response response) genereert uitzondering {return response;}});

De Luisterbare toekomst interface laat ons luisteraars toevoegen die worden uitgevoerd wanneer de HTTP-oproep is voltooid.

Laten we ook de code van de luisteraars uitvoeren - door een andere threadpool te gebruiken:

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

Bovendien is de optie om luisteraars toe te voegen, de Luisterbare toekomst interface laat ons de Toekomst reactie op een CompletableFuture.

7. Conclusie

AHC is een zeer krachtige bibliotheek, met veel interessante functies. Het biedt een zeer eenvoudige manier om een ​​HTTP-client te configureren en de mogelijkheid om zowel synchrone als asynchrone verzoeken uit te voeren.

Zoals altijd is de broncode voor het artikel beschikbaar op GitHub.


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