发送请求
概述
HTTP
客户端提供四种请求发送方式,分别是:
- 同步发送,对应于
HttpClient#send
系列方法 - 异步发送,对应于
HttpClient#sendAsync
系列方法 - 队列发送(这个类似于
Promise
模式或者是可监听结果的异步处理模式),对应于HttpClient#enqueue
系列方法 - 调度发送,对应于
HttpClient#scheduledSend
系列方法
上述任意一类API
都有一个Simple
附加方法,此附加方法会忽略响应的详细信息只保留响应有效载荷的转换结果。
同步发送
可以使用HttpClient#send()
或者HttpClient#sendSimple()
进行同步发送。举个例子:
HttpClient httpClient = Solpic.newHttpClient();
HttpRequest httpRequest = HttpRequest.newBuilder()
.method(HttpMethod.GET)
.uri(URI.create("https://httpbin.org/get"))
.build();
HttpResponse<String> r1 = httpClient.send(httpRequest, PayloadSubscribers.X.ofString());
String r2 = httpClient.sendSimple(httpRequest, PayloadSubscribers.X.ofString());
异步发送
可以使用HttpClient#sendAsync()
或者HttpClient#sendAsyncSimple()
进行异步发送。举个例子:
HttpClient httpClient = Solpic.newHttpClient();
HttpRequest httpRequest = HttpRequest.newBuilder()
.method(HttpMethod.GET)
.uri(URI.create("https://httpbin.org/get"))
.build();
CompletableFuture<HttpResponse<String>> r1 = httpClient.sendAsync(httpRequest, PayloadSubscribers.X.ofString());
CompletableFuture<String> r2 = httpClient.sendAsyncSimple(httpRequest, PayloadSubscribers.X.ofString());
队列发送
队列发送其实是一种衍生的异步发送,实现上就是可监听结果的异步发送,对应于HttpClient#enqueue()
或者HttpClient#enqueueSimple()
方法。举个例子:
HttpClient httpClient = Solpic.newHttpClient();
HttpRequest httpRequest = HttpRequest.newBuilder()
.method(HttpMethod.GET)
.uri(URI.create("https://httpbin.org/get"))
.build();
class CustomFuture extends AbstractFutureListener<String> {
@Override
protected void onSuccess(String result) {
System.out.printf("Received response payload: %s\n", result);
}
}
ListenableFuture<HttpResponse<String>> lf1 = httpClient.enqueue(httpRequest, PayloadSubscribers.X.ofString(),
new CustomFuture());
ListenableFuture<String> lf2 = httpClient.enqueueSimple(httpRequest, PayloadSubscribers.X.ofString(),
new CustomFuture());
调度发送
调度发送就是指定某个HTTP
请求在未来某个时刻发送,除了需要创建请求对象以外,还需要指定延迟发送时间和一个类型为CompletableFuture
的Promise
对象,对应于HttpClient#scheduledSend()
或者HttpClient#scheduledSendSimple()
方法。举个例子:
HttpClient httpClient = Solpic.newHttpClient();
HttpRequest httpRequest = HttpRequest.newBuilder()
.method(HttpMethod.GET)
.uri(URI.create("https://httpbin.org/get"))
.build();
CompletableFuture<HttpResponse<String>> p1 = new CompletableFuture<>();
p1.whenComplete((response, throwable) -> {
// handle result
});
CompletableFuture<String> p2 = new CompletableFuture<>();
p2.whenComplete((payload, throwable) -> {
// handle result
});
ScheduledFuture<HttpResponse<String>> sf1 = httpClient.scheduledSend(httpRequest,
PayloadSubscribers.X.ofString(), 500, TimeUnit.MILLISECONDS, p1);
ScheduledFuture<String> sf2 = httpClient.scheduledSendSimple(httpRequest,
PayloadSubscribers.X.ofString(), 500, TimeUnit.MILLISECONDS, p2);
终止请求
Solpic
中请求对象存在下面的状态序列:
INIT(初始化) -> ACTIVE(处理中) -> COMPLETED(处理成功)、FAILED(异常失败)、ABORTED(主动终止)
可以在请求对象处于INIT
或者ACTIVE
状态的时候主动终止请求发送。举个例子:
HttpClient httpClient = Solpic.newHttpClientBuilder()
.type(HttpClientType.DEFAULT)
.build();
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(URI.create("https://httpbin.org/get"))
.method(HttpMethod.GET)
.build();
httpRequest.abort();
httpClient.send(httpRequest, PayloadSubscribers.X.discarding());
某次调用结果如下:
cn.vlts.solpic.core.exception.SolpicHttpException: [DefaultHttpClient-1] - HTTP request was aborted
// 省略其他异常栈信息......
配置线程池
对于异步发送和队列发送场景,需要配置线程池ThreadPool
。对于调度发送场景,需要配置调度线程池ScheduledThreadPool
。默认情况下,Solpic
会基于SPI
增强模块延迟加载名称为default
的ThreadPool
实例和名称为default
的ScheduledThreadPool
实例。对于ThreadPool
,还可以选择common
或者virtual
(要求JDK>=21
),例如:
HttpClient httpClient = Solpic.newHttpClientBuilder()
// .option(HttpOptions.HTTP_THREAD_POOL, "virtual")
.option(HttpOptions.HTTP_THREAD_POOL, "common")
.build();
当然,也可以自定义实现线程池或者调度线程池。这里以自定义ScheduledThreadPool
举例:
public class CustomScheduledThreadPool implements ScheduledThreadPool {
private final ScheduledExecutorService pool = new ScheduledThreadPoolExecutor(1);
@Override
public ScheduledFuture<?> schedule(Runnable runnable, long l, TimeUnit timeUnit) {
return pool.schedule(runnable, l, timeUnit);
}
@Override
public <V> ScheduledFuture<V> schedule(Callable<V> callable, long l, TimeUnit timeUnit) {
return pool.schedule(callable, l, timeUnit);
}
@Override
public ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long l, long l1, TimeUnit timeUnit) {
return pool.scheduleAtFixedRate(runnable, l, l1, timeUnit);
}
@Override
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable runnable, long l, long l1, TimeUnit timeUnit) {
return pool.scheduleWithFixedDelay(runnable, l, l1, timeUnit);
}
}
在当前类路径下添加META-INF/solpic/cn.vlts.solpic.core.concurrent.ScheduledThreadPool
文件,内容如下:
custom=xx.yy.zz.CustomScheduledThreadPool
然后指定对应选项初始化HTTP
客户端即可:
HttpClient httpClient = Solpic.newHttpClientBuilder()
.option(HttpOptions.HTTP_SCHEDULED_THREAD_POOL, "custom")
.build();