在 Twitter 上关注@AsyncHttpClient。
AsyncHttpClient (AHC) 库允许 Java 应用程序轻松执行 HTTP 请求并异步处理 HTTP 响应。该库还支持 WebSocket 协议。
它构建在 Netty 之上。它是用 Java 11 编译的。
二进制文件部署在 Maven Central 上。添加对主 AsyncHttpClient 工件的依赖项:
行家:
< dependencies >
< dependency >
< groupId >org.asynchttpclient</ groupId >
< artifactId >async-http-client</ artifactId >
< version >3.0.1</ version >
</ dependency >
</ dependencies >
摇篮:
dependencies {
implementation ' org.asynchttpclient:async-http-client:3.0.1 '
}
导入 Dsl 帮助程序以使用方便的方法来引导组件:
import static org . asynchttpclient . Dsl .*;
import static org . asynchttpclient . Dsl .*;
AsyncHttpClient asyncHttpClient = asyncHttpClient ();
使用完 AsyncHttpClient 实例后,通常必须关闭它们(调用close
方法),通常是在关闭应用程序时。如果不这样做,您将遇到线程挂起和资源泄漏的情况。
AsyncHttpClient 实例旨在成为与应用程序共享相同生命周期的全局资源。通常,如果您为每个请求创建一个新客户端,AHC 通常会表现不佳,因为它将为每个请求创建新线程和连接池。可以预先创建共享资源(EventLoop 和 Timer)并将它们传递给配置中的多个客户端实例。然后,您将负责关闭这些共享资源。
最后,您还可以通过 AsyncHttpClientConfig 对象配置 AsyncHttpClient 实例:
import static org . asynchttpclient . Dsl .*;
AsyncHttpClient c = asyncHttpClient ( config (). setProxyServer ( proxyServer ( "127.0.0.1" , 38080 )));
AHC 提供了 2 个 API 来定义请求:绑定请求和非绑定请求。 AsyncHttpClient
和 Dsl` 提供标准 HTTP 方法(POST、PUT 等)的方法,但您也可以传递自定义方法。
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 );
使用setBody
方法向请求添加正文。
该主体可以是以下类型:
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
是一个通用抽象,可让您动态创建请求主体。如果您正在寻找一种动态传递请求块的方法,请查看FeedableBodyGenerator
。
使用addBodyPart
方法将多部分添加到请求中。
该部分可以是以下类型:
ByteArrayPart
FilePart
InputStreamPart
StringPart
execute
方法返回java.util.concurrent.Future
。您可以简单地阻止调用线程来获取响应。
Future < Response > whenResponse = asyncHttpClient . prepareGet ( "http://www.example.com/" ). execute ();
Response response = whenResponse . get ();
这对于调试很有用,但在生产中运行此类代码时很可能会损害性能或产生错误。使用非阻塞客户端的要点是不阻塞调用线程!
execute
方法实际上返回一个类似于Guava的org.asynchttpclient.ListenableFuture
。您可以配置侦听器以接收 Future 完成的通知。
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 );
如果executor
参数为null,回调将在IO线程中执行。你绝对不能在那里执行阻塞操作,通常是发送另一个请求并阻塞未来。
execute
方法可以使用org.asynchttpclient.AsyncHandler
来接收不同事件的通知,例如接收状态、标头和正文块。当您不指定时,AHC 将使用org.asynchttpclient.AsyncCompletionHandler
;
AsyncHandler
方法可以让您提前中止处理(返回AsyncHandler.State.ABORT
),并可以让您从onCompleted
返回计算结果,该结果将用作 Future 的结果。请参阅AsyncCompletionHandler
实现作为示例。
下面的示例仅捕获响应状态并跳过处理响应正文块。
请注意,返回ABORT
会关闭底层连接。
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
有一个toCompletableFuture
方法,该方法返回CompletableFuture
。请注意,取消此CompletableFuture
不会正确取消正在进行的请求。我们很有可能会在下一个版本中返回CompletionStage
。
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
您可以从 org.asynchttpclient.example 获得这个简单演示的完整 Maven 项目
异步 Http 客户端还支持 WebSocket。您需要传递一个WebSocketUpgradeHandler
来注册WebSocketListener
。
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 ();
加入异步 HTTP 客户端讨论组,了解库开发的最新动态
GitHub 讨论