最近在做新一代devopts微服务架构相关的东西,服务之间的注册于发现时基于etcd去做的,这里涉及异步请求调用,异步消息的返回等方面。现在说说

在其中用到的AsyncHttpClient这个异步调用类。

Async Http Client库简单易用,旨在让Java应用可以轻松执行HTTP请求和异步处理HTTP响应。同时也支持WebSockets协议。

首先,你要在你的项目里引入AsyncHttpClient,如果你使用maven来构建,可以很简单的引入:

  dependency>

        <groupId>com.ning</groupId>

         <artifactId>async-http-client</artifactId>

          <version>1.9.0</version>

</dependency>

然后关于它的调用,举例实例代码:稍后介绍自己的实现:

importcom.ning.http.client.*;

importjava.util.concurrent.Future;

 

AsyncHttpClientasyncHttpClient = new AsyncHttpClient();

Future<Response>f = asyncHttpClient.prepareGet("http://www.ning.com/").execute();

Responser = f.get();

以上是最简单的一种使用方法,注意在这个例子中所有的应答内容都必须预先读到内存中,即使你使用的是getResponseBodyAsStream()方法来获取结果。

你可以在handler里对应答作出操作,这尤其在andorid系统显得很重要。以下是示例代码:

importcom.ning.http.client.*;

importjava.util.concurrent.Future;

 

AsyncHttpClientasyncHttpClient = new AsyncHttpClient();

asyncHttpClient.prepareGet("http://www.ning.com/").execute(newAsyncCompletionHandler<Response>(){

 

    @Override

    public Response onCompleted(Responseresponse) throws Exception{

        // Do something with the Response

        // ...

        return response;

    }

 

    @Override

    public void onThrowable(Throwable t){

        // Something wrong happened.

    }

});

(这种方式同样会预先把response读取到内存中。)

            你还可以混合使用以上两种方式,这样可以只读取整个response内容的一部分。以下是示例代码:

importcom.ning.http.client.*;

importjava.util.concurrent.Future;

 

AsyncHttpClientasyncHttpClient = new AsyncHttpClient();

Future<Integer>f = asyncHttpClient.prepareGet("http://www.ning.com/").execute(

   new AsyncCompletionHandler<Integer>(){

 

    @Override

    public Integer onCompleted(Responseresponse) throws Exception{

        // Do something with the Response

        return response.getStatusCode();

    }

 

    @Override

   public void onThrowable(Throwable t){

        // Something wrong happened.

    }

});

 

intstatusCode = f.get();

这种情况下我们就只读取了一个状态码。

当你预期获取的内容比较大时,只要应答已经可读,你就可以一段一段的读取它,而不是把整个内容都先读到内存中。

            该库还有一个大的优点就是你可以完全控制整个response的生命周期,因此你可以决定在任意时刻停止接受服务器的返回。示例代码如下:

            import com.ning.http.client.*;

importjava.util.concurrent.Future;

 

AsyncHttpClientc = new AsyncHttpClient();

Future<String>f = c.prepareGet("http://www.ning.com/").execute(newAsyncHandler<String>() {

    private ByteArrayOutputStream bytes = newByteArrayOutputStream();

 

    @Override

    public STATEonStatusReceived(HttpResponseStatus status) throws Exception {

        int statusCode = status.getStatusCode();

        // The Status have been read

        // If you don't want to read theheaders,body or stop processing the response

        if (statusCode >= 500) {

            return STATE.ABORT;

        }

    }

 

    @Override

    public STATEonHeadersReceived(HttpResponseHeaders h) throws Exception {

        Headers headers = h.getHeaders();

         // The headers have been read

         // If you don't want to read the body,or stop processing the response

         return STATE.ABORT;

    }

 

    @Override

    public STATEonBodyPartReceived(HttpResponseBodyPart bodyPart) throws Exception {

        bytes.write(bodyPart.getBodyPartBytes());

         return STATE.CONTINUE;

    }

 

    @Override

    public String onCompleted() throwsException {

         // Will be invoked once the responsehas been fully read or a ResponseComplete exception

         // has been thrown.

         // NOTE: should probably useContent-Encoding from headers

         return bytes.toString("UTF-8");

    }

 

    @Override

    public void onThrowable(Throwable t) {

    }

});

 

StringbodyResponse = f.get();

通过代码可以看出,我们可以控制读取的内容,比如只读取状态码,读取到header信息为止,读取完body为止,完全读取成功等等。

            我们可以通过AsynHttpClientConfig类为你的应用程序设置代理服务器和端口。示例代码如下:

AsyncHttpClientConfigcf = new AsyncHttpClientConfig.Builder()

    S.setProxyServer(newProxyServer("127.0.0.1", 38080)).build();

AsyncHttpClientc = new AsyncHttpClient(cf);


3、在自己项目调用中,自己进行了封装,具体如下:


final SettableFuture<Response> future = SettableFuture.create();
httpClient.executeRequest(request, new AsyncCompletionHandler<Response>(){

@Override
public Response onCompleted(Response response) throws Exception {
future.set(response);
return response;
}

@Override
public void onThrowable(Throwable t) {
logger.error(t.getMessage(), t);
super.onThrowable(t);
future.setException(t);
}

});

return future;


ok,以上是自己对于异步调用类的总结。




Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐