트위터에서 @AsyncHttpClient를 팔로우하세요.
AHC(AsyncHttpClient) 라이브러리를 사용하면 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
반환) Future의 결과로 사용될 onCompleted
에서 계산 결과를 반환할 수 있습니다. 예제로 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
에는 CompletableFuture
를 반환하는 toCompletableFuture
메서드가 있습니다. 이 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 프로젝트를 얻을 수 있습니다.
Async Http Client는 WebSocket도 지원합니다. WebSocketListener
를 등록할 곳에 WebSocketUpgradeHandler
전달해야 합니다.
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 토론