如何获得使用JDK的HttpClient订阅的响应的状态码?

时间:2019-05-07 14:40:59

标签: java java-11 jdk-httpclient

Java 11引入了新标准HTTP client。使用HttpClient:send发送请求,该请求返回HttpResponse

HttpResponse::statusCode方法可用于查找响应的HTTP状态。

HttpClient::send也采用BodyHandler,该Flow.Subscription用于处理响应的正文。 BodyHandler的有用家族是包裹由BodyHandlers::fromSubscriber和亲戚创建的server-sent events的家族。这些是处理无限数据流(例如As noted in the documentation)的有用方法。

但是,似乎如果您使用这些BodyHandler中的一个,则流将在称为HttpClient::send的线程上传递,因此对于无限流,该方法将永远不会返回。由于它永远不会返回,因此您永远不会获得HttpResponse来确定状态。

那么,如何获得我订阅的回复的状态代码?

1 个答案:

答案 0 :(得分:2)

{{3}},这BodyHandler

  

不检查状态码,这意味着始终可以接受尸体

带有提示

  

自定义处理程序可用于检查状态代码和标头,并根据需要返回相同类型的其他主体订户

似乎没有便利的方法或类,但是这种事情相当简单:

// a subscriber which expresses a complete lack of interest in the body
private static class Unsubscriber implements HttpResponse.BodySubscriber<Void> {
    @Override
    public CompletionStage<Void> getBody() {
        return CompletableFuture.completedStage(null);
    }

    @Override
    public void onSubscribe(Flow.Subscription subscription) {
        subscription.cancel();
    }

    @Override
    public void onNext(List<ByteBuffer> item) {}

    @Override
    public void onError(Throwable throwable) {}

    @Override
    public void onComplete() {}
}


// wraps another handler, and only uses it for an expected status
private static HttpResponse.BodyHandler<Void> expectingStatus(int expected, HttpResponse.BodyHandler<Void> handler) {
    return responseInfo -> responseInfo.statusCode() == expected ? handler.apply(responseInfo) : new Unsubscriber();
}

// used like this
Flow.Subscriber<String> subscriber = createSubscriberSomehow();
HttpResponse<Void> response = HttpClient.newHttpClient()
                                        .send(HttpRequest.newBuilder()
                                                         .uri(URI.create("http://example.org/api"))
                                                         .build(),
                                              expectingStatus(200, HttpResponse.BodyHandlers.fromLineSubscriber(subscriber)));