在 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 討論