Spring Boot 2关于http接口调用2
使用HttpAsyncClient
这里主要使用apache的 HttpComponents
http://hc.apache.org/index.html
https://mvnrepository.com/artifact/org.apache.httpcomponents/httpasyncclient
HttpAsyncClient中常用的接口
<T> Future<T> execute(HttpAsyncRequestProducer requestProducer, HttpAsyncResponseConsumer<T> responseConsumer, HttpContext context, FutureCallback<T> callback);
<T> Future<T> execute(HttpAsyncRequestProducer requestProducer, HttpAsyncResponseConsumer<T> responseConsumer, FutureCallback<T> callback);
Future<HttpResponse> execute(HttpHost target, HttpRequest request, HttpContext context, FutureCallback<HttpResponse> callback);
Future<HttpResponse> execute(HttpHost target, HttpRequest request, FutureCallback<HttpResponse> callback);
Future<HttpResponse> execute(HttpUriRequest request, HttpContext context, FutureCallback<HttpResponse> callback);
Future<HttpResponse> execute(HttpUriRequest request, FutureCallback<HttpResponse> callback);
HttpAsyncClient重要的实现类CloseableHttpAsyncClient
创建连接
1.默认HttpAsyncClients.createDefault
CloseableHttpAsyncClient httpClient = HttpAsyncClients.createDefault();
httpClient.start();
// 其他操作
httpClient.close();
2.自定义参数创建
// 设置请求超时时间配置
public static RequestConfig getRequestConfig() {
return RequestConfig.custom()
.setConnectTimeout(CONNECT_TIMEOUT)
.setSocketTimeout(SOCKET_TIMEOUT)
.setConnectionRequestTimeout(CONNECT_REQUEST_TIMEOUT)
.build();
}
// 连接池参数配置
public static PoolingNHttpClientConnectionManager getPoolingNHttpClientConnectionManager() throws IOReactorException {
SSLContext sslContext = SSLContexts.createDefault();
/**
* 设置协议http和https对应的处理socket链接工厂的对象
*/
Registry<SchemeIOSessionStrategy> sessionStrategyRegistry = RegistryBuilder
.<SchemeIOSessionStrategy>create()
.register("http", NoopIOSessionStrategy.INSTANCE)
.register("https", new SSLIOSessionStrategy(sslContext))
.build();
/**
* 配置IO线程
*/
IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
.setIoThreadCount(Runtime.getRuntime().availableProcessors())
.build();
/**
* 设置连接池大小
*/
ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(ioReactorConfig);
PoolingNHttpClientConnectionManager conMgr = new PoolingNHttpClientConnectionManager(ioReactor, null, sessionStrategyRegistry, null);
if (POOL_SIZE > 0) {
conMgr.setMaxTotal(POOL_SIZE);
}
if (MAX_PER_ROUTE > 0) {
conMgr.setDefaultMaxPerRoute(MAX_PER_ROUTE);
} else {
conMgr.setDefaultMaxPerRoute(10);
}
ConnectionConfig connectionConfig = ConnectionConfig.custom()
.setMalformedInputAction(CodingErrorAction.IGNORE)
.setUnmappableInputAction(CodingErrorAction.IGNORE)
.setCharset(Consts.UTF_8).build();
conMgr.setDefaultConnectionConfig(connectionConfig);
return conMgr;
}
// 创建连接
public static CloseableHttpAsyncClient createAsyncClient() throws IOReactorException {
PoolingNHttpClientConnectionManager conMgr = getPoolingNHttpClientConnectionManager();
Lookup<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder
.<AuthSchemeProvider>create()
.register(AuthSchemes.BASIC, new BasicSchemeFactory())
.register(AuthSchemes.DIGEST, new DigestSchemeFactory())
.register(AuthSchemes.NTLM, new NTLMSchemeFactory())
.register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory())
.register(AuthSchemes.KERBEROS, new KerberosSchemeFactory())
.build();
return HttpAsyncClients.custom().setConnectionManager(conMgr)
.setDefaultAuthSchemeRegistry(authSchemeRegistry)
.setDefaultCookieStore(new BasicCookieStore())
.setDefaultRequestConfig(getRequestConfig()).build();
}
调用方式
1.Future模式
// 关键代码
Future<HttpResponse> future = httpClient.execute(builder.getHttpRequestBase(), null);
HttpResponse response = future.get();
2.FutureCallback模式
// 关键代码
httpClient.execute(requestBuilder.getHttpRequestBase(), new FutureCallback<HttpResponse>() {
@Override
public void completed(final HttpResponse response) {
}
@Override
public void failed(final Exception ex) {
}
@Override
public void cancelled() {
}
});
}
单元测试
// 单次Future测试
@Test
public void test1() {
long begin = System.currentTimeMillis();
HttpRequestBuilder httpRequestBuilder = new HttpRequestBuilder()
.build(HttpMethod.GET, "http://localhost:9999/demo/hello")
.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);
HttpRspDTO<String> rspDTO = HttpAsyncClientHelper.invoke(httpRequestBuilder, HttpRspDTO.class, null, String.class);
long end = System.currentTimeMillis();
System.out.println("*****消耗时间(秒):" + (end - begin) / 1000.0);
System.out.println(rspDTO);
}
// 批量Future测试
@Test
public void test2() {
long begin = System.currentTimeMillis();
List<HttpRequestBuilder> requestBuilderList = new ArrayList<HttpRequestBuilder>();
for (int i = 0; i < 100; i++) {
HttpRequestBuilder httpRequestBuilder = new HttpRequestBuilder()
.build(HttpMethod.GET, "http://localhost:9999/demo/hello")
.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);
requestBuilderList.add(httpRequestBuilder);
}
List<HttpRspDTO<String>> rspDTOList = HttpAsyncClientHelper.invoke(requestBuilderList, HttpRspDTO.class, null, String.class);
long end = System.currentTimeMillis();
System.out.println("*****消耗时间(秒):" + (end - begin) / 1000.0);
System.out.println(rspDTOList != null ? rspDTOList.stream().filter(Objects::nonNull).filter(it -> Objects.equals(Boolean.TRUE, it.getSuccess())).count() : 0);
}
// 批量Callback
@Test
public void test3() {
long begin = System.currentTimeMillis();
List<HttpRequestBuilder> requestBuilderList = new ArrayList<HttpRequestBuilder>();
for (int i = 0; i < 100; i++) {
HttpRequestBuilder httpRequestBuilder = new HttpRequestBuilder()
.build(HttpMethod.GET, "http://localhost:9999/demo/hello")
.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);
requestBuilderList.add(httpRequestBuilder);
}
List<String> resultList = new ArrayList<String>();
HttpAsyncClientHelper.invoke(requestBuilderList, HttpRspDTO.class, null, new Type[]{String.class}, new HttpResultCallback<HttpRspDTO<String>>() {
@Override
public void handle(HttpRspDTO<String> result) {
//System.out.println("#####返回结果:" + result);
if (result != null && Objects.equals(Boolean.TRUE, result.getSuccess())) {
resultList.add(result.getData());
}
}
});
long end = System.currentTimeMillis();
System.out.println("*****消耗时间(秒):" + (end - begin) / 1000.0);
System.out.println(resultList.size());
}
源码位置
https://gitee.com/ceclar123/spring-boot-demo/tree/master/ch01