Folgen Sie @AsyncHttpClient auf Twitter.
Die AsyncHttpClient (AHC)-Bibliothek ermöglicht Java-Anwendungen die einfache Ausführung von HTTP-Anfragen und die asynchrone Verarbeitung von HTTP-Antworten. Die Bibliothek unterstützt auch das WebSocket-Protokoll.
Es basiert auf Netty. Es ist mit Java 11 kompiliert.
Binärdateien werden auf Maven Central bereitgestellt. Fügen Sie eine Abhängigkeit vom Hauptartefakt AsyncHttpClient hinzu:
Maven:
< dependencies >
< dependency >
< groupId >org.asynchttpclient</ groupId >
< artifactId >async-http-client</ artifactId >
< version >3.0.1</ version >
</ dependency >
</ dependencies >
Gradle:
dependencies {
implementation ' org.asynchttpclient:async-http-client:3.0.1 '
}
Importieren Sie die Dsl-Helfer, um praktische Methoden zum Bootstrapping von Komponenten zu verwenden:
import static org . asynchttpclient . Dsl .*;
import static org . asynchttpclient . Dsl .*;
AsyncHttpClient asyncHttpClient = asyncHttpClient ();
AsyncHttpClient-Instanzen müssen geschlossen werden (rufen Sie die Methode close
auf), sobald Sie mit ihnen fertig sind, normalerweise beim Herunterfahren Ihrer Anwendung. Wenn Sie dies nicht tun, kommt es zu hängenden Threads und Ressourcenlecks.
AsyncHttpClient-Instanzen sollen globale Ressourcen sein, die denselben Lebenszyklus wie die Anwendung haben. Wenn Sie für jede Anfrage einen neuen Client erstellen, ist AHC in der Regel leistungsschwach, da für jede Anfrage neue Threads und Verbindungspools erstellt werden. Es ist möglich, vorab gemeinsam genutzte Ressourcen (EventLoop und Timer) zu erstellen und diese in der Konfiguration an mehrere Client-Instanzen zu übergeben. Sie sind dann dafür verantwortlich, diese freigegebenen Ressourcen zu schließen.
Schließlich können Sie die AsyncHttpClient-Instanz auch über ihr AsyncHttpClientConfig-Objekt konfigurieren:
import static org . asynchttpclient . Dsl .*;
AsyncHttpClient c = asyncHttpClient ( config (). setProxyServer ( proxyServer ( "127.0.0.1" , 38080 )));
AHC bietet zwei APIs zum Definieren von Anforderungen: gebunden und ungebunden. AsyncHttpClient
und Dsl` stellen Methoden für Standard-HTTP-Methoden (POST, PUT usw.) bereit, Sie können aber auch eine benutzerdefinierte Methode übergeben.
import org . asynchttpclient .*;
// bound
Future < Response > whenResponse = asyncHttpClient . prepareGet ( "http://www.example.com/" ). execute ();
// unbound
Request request = get ( "http://www.example.com/" ). build ();
Future < Response > whenResponse = asyncHttpClient . executeRequest ( request );
Verwenden Sie die setBody
-Methode, um der Anfrage einen Text hinzuzufügen.
Dieser Körper kann folgender Art sein:
java.io.File
byte[]
List<byte[]>
String
java.nio.ByteBuffer
java.io.InputStream
Publisher<io.netty.buffer.ByteBuf>
org.asynchttpclient.request.body.generator.BodyGenerator
BodyGenerator
ist eine generische Abstraktion, mit der Sie Anforderungstexte im laufenden Betrieb erstellen können. Schauen Sie sich FeedableBodyGenerator
an, wenn Sie nach einer Möglichkeit suchen, Anfrageblöcke im laufenden Betrieb weiterzuleiten.
Verwenden Sie die Methode addBodyPart
, um der Anfrage einen mehrteiligen Teil hinzuzufügen.
Dieser Teil kann folgender Art sein:
ByteArrayPart
FilePart
InputStreamPart
StringPart
execute
geben ein java.util.concurrent.Future
zurück. Sie können einfach den aufrufenden Thread blockieren, um die Antwort zu erhalten.
Future < Response > whenResponse = asyncHttpClient . prepareGet ( "http://www.example.com/" ). execute ();
Response response = whenResponse . get ();
Dies ist zum Debuggen nützlich, aber Sie werden höchstwahrscheinlich die Leistung beeinträchtigen oder Fehler verursachen, wenn Sie solchen Code in der Produktion ausführen. Der Sinn der Verwendung eines nicht blockierenden Clients besteht darin, den aufrufenden Thread NICHT zu BLOCKIEREN !
execute
geben tatsächlich ein org.asynchttpclient.ListenableFuture
zurück, das dem von Guava ähnelt. Sie können Listener so konfigurieren, dass sie über den Abschluss der Zukunft benachrichtigt werden.
ListenableFuture < Response > whenResponse = ???;
Runnable callback = () - > {
try {
Response response = whenResponse . get ();
System . out . println ( response );
} catch ( InterruptedException | ExecutionException e ) {
e . printStackTrace ();
}
};
java . util . concurrent . Executor executor = ???;
whenResponse . addListener (() - > ??? , executor );
Wenn der executor
-Parameter null ist, wird der Rückruf im E/A-Thread ausgeführt. Sie DÜRFEN dort NIEMALS BLOCKIERENDE Operationen DURCHFÜHREN , indem Sie normalerweise eine weitere Anfrage senden und eine zukünftige Blockierung vornehmen.
execute
können einen org.asynchttpclient.AsyncHandler
benötigen, um über die verschiedenen Ereignisse benachrichtigt zu werden, z. B. den Empfang des Status, der Header und Body-Chunks. Wenn Sie keinen angeben, verwendet AHC einen org.asynchttpclient.AsyncCompletionHandler
;
AsyncHandler
-Methoden können Sie die Verarbeitung vorzeitig abbrechen ( AsyncHandler.State.ABORT
zurückgeben) und ein Berechnungsergebnis von onCompleted
zurückgeben, das als Ergebnis der Zukunft verwendet wird. Sehen Sie sich AsyncCompletionHandler
-Implementierung als Beispiel an.
Das folgende Beispiel erfasst lediglich den Antwortstatus und überspringt die Verarbeitung der Antworttextblöcke.
Beachten Sie, dass die Rückgabe von ABORT
die zugrunde liegende Verbindung schließt.
import static org . asynchttpclient . Dsl .*;
import org . asynchttpclient .*;
import io . netty . handler . codec . http . HttpHeaders ;
Future < Integer > whenStatusCode = asyncHttpClient . prepareGet ( "http://www.example.com/" )
. execute ( new AsyncHandler < Integer > () {
private Integer status ;
@ Override
public State onStatusReceived ( HttpResponseStatus responseStatus ) throws Exception {
status = responseStatus . getStatusCode ();
return State . ABORT ;
}
@ Override
public State onHeadersReceived ( HttpHeaders headers ) throws Exception {
return State . ABORT ;
}
@ Override
public State onBodyPartReceived ( HttpResponseBodyPart bodyPart ) throws Exception {
return State . ABORT ;
}
@ Override
public Integer onCompleted () throws Exception {
return status ;
}
@ Override
public void onThrowable ( Throwable t ) {
t . printStackTrace ();
}
});
Integer statusCode = whenStatusCode . get ();
ListenableFuture
verfügt über eine toCompletableFuture
-Methode, die ein CompletableFuture
zurückgibt. Beachten Sie, dass durch das Abbrechen dieses CompletableFuture
die laufende Anfrage nicht ordnungsgemäß abgebrochen wird. Es besteht eine sehr gute Chance, dass wir in der nächsten Version stattdessen eine CompletionStage
zurückgeben.
CompletableFuture < Response > whenResponse = asyncHttpClient
. prepareGet ( "http://www.example.com/" )
. execute ()
. toCompletableFuture ()
. exceptionally ( t ->{ /* Something wrong happened... */ })
. thenApply ( response ->{ /* Do something with the Response */ return resp ;});
whenResponse . join (); // wait for completion
Das vollständige Maven-Projekt für diese einfache Demo erhalten Sie möglicherweise von org.asynchttpclient.example
Der Async-HTTP-Client unterstützt auch WebSocket. Sie müssen einen WebSocketUpgradeHandler
übergeben, an dem Sie einen WebSocketListener
registrieren würden.
WebSocket websocket = c . prepareGet ( "ws://demos.kaazing.com/echo" )
. execute ( new WebSocketUpgradeHandler . Builder (). addWebSocketListener (
new WebSocketListener () {
@ Override
public void onOpen ( WebSocket websocket ) {
websocket . sendTextFrame ( "..." ). sendTextFrame ( "..." );
}
@ Override
public void onClose ( WebSocket websocket ) {
// ...
}
@ Override
public void onTextFrame ( String payload , boolean finalFragment , int rsv ) {
System . out . println ( payload );
}
@ Override
public void onError ( Throwable t ) {
t . printStackTrace ();
}
}). build ()). get ();
Bleiben Sie über die Entwicklung der Bibliothek auf dem Laufenden, indem Sie der Diskussionsgruppe „Asynchroner HTTP-Client“ beitreten
GitHub-Diskussionen