Java异步HTTP请求
需要用到的包(包版本应该可能不同):
httpcore-4.1.4.jar
httpsayncclient-4.0-alpha3.jar
httpcore-nio-4.2-alpha3.jar
代码(来自http://hc.apache.org/httpcomponents-asyncclient-dev/httpasyncclient/examples/org/apache/http/examples/nio/client/AsyncClientHttpExchangeStreaming.java):
[java]
view plain copy
- /*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.The ASF licenses this file!
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.You may obtain a copy of the License at
- *
- *http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.For more
- * information on the Apache Software Foundation, please see
- * .
- *
- */
- package sync_http;
- import java.io.IOException;
- import java.nio.CharBuffer;
- import java.util.concurrent.Future;
- import org.apache.http.HttpResponse;
- import org.apache.http.impl.nio.client.DefaultHttpAsyncClient;
- import org.apache.http.nio.IOControl;
- import org.apache.http.nio.client.HttpAsyncClient;
- import org.apache.http.nio.client.methods.AsyncCharConsumer;
- import org.apache.http.nio.client.methods.HttpAsyncMethods;
- import org.apache.http.protocol.HttpContext;
- public class AsyncClientHttpExchangeStreaming {
- public static void main(String[] args) throws Exception {
- HttpAsyncClient httpclient = new DefaultHttpAsyncClient();
- httpclient.start();
- try {
- Future
future = httpclient.execute( - HttpAsyncMethods.createGet("http://www.baidu.com/"),
- new MyResponseConsumer(), null);
- Boolean result = future.get();
- if (result != null && result.booleanValue()) {
- System.out.println("Request successfully executed");
- } else {
- System.out.println("Request failed");
- }
- System.out.println("Shutting down");
- } finally {
- httpclient.shutdown();
- }
- System.out.println("Done");
- }
- static class MyResponseConsumer extends AsyncCharConsumer
{ - private int times = 0;
- private String getTimes() {
- return "\n\n### 第" + ++times + "步\n###";
- }
- @Override
- protected void onResponseReceived(final HttpResponse response) {
- System.out.println(getTimes() + "onResponseReceived");
- }
- @Override
- protected void onCharReceived(final CharBuffer buf, final IOControl ioctrl) throws IOException {
- System.out.println(getTimes() + "onCharReceived");
- while (buf.hasRemaining()) {
- System.out.print(buf.get());
- }
- }
- @Override
- protected void releaseResources() {
- System.out.println(getTimes() + "releaseResources");
- }
- @Override
- protected Boolean buildResult(final HttpContext context) {
- System.out.println(getTimes() + "buildResult");
- return Boolean.TRUE;
- }
- }
- }
更多官方例子,参看:http://hc.apache.org/httpcomponents-asyncclient-dev/examples.html
java.util.concurrent中主要包括三类工具,Executor Freamework,并发集合(Concurrent Collection),以及同步器(Synchronizer)。下面的例子是利用java.util.concurrent.Future只请求一个url异步请求。Future接口表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用 get 方法来获取结果,如有必要,计算完成前可以阻塞此方法。取消则由 cancel 方法来执行。还提供了其他方法,以确定任务是正常完成还是被取消了。一旦计算完成,就不能再取消计算。如果为了可取消性而使用 Future 但又不提供可用的结果,则可以声明 Future> 形式类型、并返回 null 作为底层任务的结果。
import java.util.concurrent.Future;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
/**
* This example demonstrates a basic asynchronous HTTP request / response
* exchange. Response content is buffered in memory for simplicity.
*/
public class AsyncClientHttpExchange {
public static void main(final String[] args) throws Exception {
CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault(); // 默认的配置
try {
httpclient.start();
HttpGet request = new HttpGet("http://www.apache.org/");
Future future = httpclient.execute(request, null);
HttpResponse response = future.get(); // 获取结果
System.out.println("Response: " + response.getStatusLine());
System.out.println("Shutting down");
} finally {
httpclient.close();
}
System.out.println("Done");
}
}
【Java异步HTTP请求】同步器(Synchronizer)是一些使线程能够等待另一个线程的对象,允许它们协作,最常用的同步器是CountDownLatch和Semaphore。较不常用的是CyclicBarrier和Exchanger。Semaphore类是一个计数信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动。 CountDownLatch是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 方法会一直受阻塞。之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。如果需要重置计数,可使用 CyclicBarrier。倒计数索存器(CountDownLatch)是一次性的障碍。它的唯一构造器带有一个int类型的参数,这个参数是指允许所有的等待线程处理之前,必须在锁存器上调用countDown()方法的次数。这一点非常有用。下面是异步请求一组url的例子,利用callback借口完成独立的操作。
import java.util.concurrent.CountDownLatch;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
/**
* This example demonstrates a fully asynchronous execution of multiple HTTP
* exchanges where the result of an individual operation is reported using a
* callback interface.
*/
public class AsyncClientHttpExchangeFutureCallback {
public static void main(final String[] args) throws Exception {
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(3000).setConnectTimeout(3000).build();
CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom()
.setDefaultRequestConfig(requestConfig).build();
try {
httpclient.start();
final HttpGet[] requests = new HttpGet[] {
new HttpGet("http://www.apache.org/"),
new HttpGet("https://www.verisign.com/"),
new HttpGet("http://www.google.com/"),
new HttpGet("http://www.baidu.com/") };
final CountDownLatch latch = new CountDownLatch(requests.length);
for (final HttpGet request : requests) {
httpclient.execute(request, new FutureCallback() {
//无论完成还是失败都调用countDown()
@Override
public void completed(final HttpResponse response) {
latch.countDown();
System.out.println(request.getRequestLine() + "->"
+ response.getStatusLine());
}
@Override
public void failed(final Exception ex) {
latch.countDown();
System.out.println(request.getRequestLine() + "->" + ex);
}
@Override
public void cancelled() {
latch.countDown();
System.out.println(request.getRequestLine()
+ " cancelled");
}
});
}
latch.await();
System.out.println("Shutting down");
} finally {
httpclient.close();
}
System.out.println("Done");
}
}
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 画解算法(1.|画解算法:1. 两数之和)
- 事件代理
- Java|Java OpenCV图像处理之SIFT角点检测详解
- java中如何实现重建二叉树
- 数组常用方法一
- 【Hadoop踩雷】Mac下安装Hadoop3以及Java版本问题
- ts泛型使用举例
- Java|Java基础——数组
- RxJava|RxJava 在Android项目中的使用(一)