Skip to content

发送请求

概述

HTTP客户端提供四种请求发送方式,分别是:

  • 同步发送,对应于HttpClient#send系列方法
  • 异步发送,对应于HttpClient#sendAsync系列方法
  • 队列发送(这个类似于Promise模式或者是可监听结果的异步处理模式),对应于HttpClient#enqueue系列方法
  • 调度发送,对应于HttpClient#scheduledSend系列方法

上述任意一类API都有一个Simple附加方法,此附加方法会忽略响应的详细信息只保留响应有效载荷的转换结果

同步发送

可以使用HttpClient#send()或者HttpClient#sendSimple()进行同步发送。举个例子:

java
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()进行异步发送。举个例子:

java
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()方法。举个例子:

java
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请求在未来某个时刻发送,除了需要创建请求对象以外,还需要指定延迟发送时间和一个类型为CompletableFuturePromise对象,对应于HttpClient#scheduledSend()或者HttpClient#scheduledSendSimple()方法。举个例子:

java
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中请求对象存在下面的状态序列:

properties
INIT(初始化) -> ACTIVE(处理中) -> COMPLETED(处理成功)、FAILED(异常失败)、ABORTED(主动终止)

可以在请求对象处于INIT或者ACTIVE状态的时候主动终止请求发送。举个例子:

java
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());

某次调用结果如下:

shell
cn.vlts.solpic.core.exception.SolpicHttpException: [DefaultHttpClient-1] - HTTP request was aborted
// 省略其他异常栈信息......

配置线程池

对于异步发送和队列发送场景,需要配置线程池ThreadPool。对于调度发送场景,需要配置调度线程池ScheduledThreadPool。默认情况下,Solpic会基于SPI增强模块延迟加载名称为defaultThreadPool实例和名称为defaultScheduledThreadPool实例。对于ThreadPool,还可以选择common或者virtual(要求JDK>=21),例如:

java
HttpClient httpClient = Solpic.newHttpClientBuilder()
//       .option(HttpOptions.HTTP_THREAD_POOL, "virtual")
        .option(HttpOptions.HTTP_THREAD_POOL, "common")
        .build();

当然,也可以自定义实现线程池或者调度线程池。这里以自定义ScheduledThreadPool举例:

java
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文件,内容如下:

properties
custom=xx.yy.zz.CustomScheduledThreadPool

然后指定对应选项初始化HTTP客户端即可:

java
HttpClient httpClient = Solpic.newHttpClientBuilder()
        .option(HttpOptions.HTTP_SCHEDULED_THREAD_POOL, "custom")
        .build();

贡献者

页面历史

Released under the MIT License.