Java11引入了一个新的标准HTTP client。使用返回HttpResponse的HttpClient:send发送请求。
HttpResponse::statusCode方法可用于查找响应的HTTP状态。
HttpClient::send还接受一个用于处理响应正文的BodyHandler。一个有用的BodyHandler家族是那些包装了Flow.Subscription的家族,它们是用BodyHandlers::fromSubscriber和相关成员创建的。这些是处理无限数据流的有用方法,例如server-sent events。
但是,如果您使用这些BodyHandler中的一个,流似乎是在名为HttpClient::send的线程上传递的,因此对于无限流,该方法永远不会返回。因为它永远不会返回,所以您永远得不到可以用来确定状态的HttpResponse。
那么,我如何获得我订阅的响应的状态代码呢?
发布于 2019-05-07 22:40:59
As noted in the documentation,这些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)));https://stackoverflow.com/questions/56025114
复制相似问题