tbjorch的回答让我走上了正确的道路,但我发现的一件事是我应该使用 和 的静态方法构造HTTP.create
异常。如果我不这样做,我的所有异常都将作为超类抛出,这是不可取的,因为它丢失了原始 Http 状态代码的上下文。HttpClientErrorException
HttpServerErrorException
Exception
我是使用 Spring WebClient 的新手。我正在实现的 API 根据成功或失败使用不同的 JSON 结构进行响应。在失败的情况下,我希望能够反序列化响应正文并返回错误消息。根据下面的代码,我收到一条错误消息:
java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio-2
at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:83)
我同意,在 2 个地方屏蔽是没有意义的。但我不明白如何反序列化错误响应以获取错误消息。我在网上和 StackOverflow 上阅读的所有内容都表明人们只是返回Mono.error
或抛出异常,但在这些情况下他们似乎没有反序列化响应正文。这是我的代码:
public boolean updatePassword(String id, String data) {
final var responseSpec =
client
.post()
.uri(builder -> builder.path("/{id}/change_password").build(id))
.header(HttpHeaders.AUTHORIZATION, "Bearer " + staticData.getAPIToken())
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(data))
.retrieve()
.onStatus(
HttpStatus::isError,
error -> {
final var errorResponse = error.bodyToMono(ErrorResponse.class).block();
final var errorMsg = errorResponse.getCause().getSummary();
if (error.statusCode().is4xxClientError()) {
throw new HttpClientErrorException(error.statusCode(), errorMsg);
}
if (error.statusCode().is5xxServerError()) {
throw new HttpServerErrorException(error.statusCode(), errorMsg);
}
return Mono.error(
new HttpServerErrorException(
HttpStatus.INTERNAL_SERVER_ERROR, "Something else."));
})
.bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {});
final var response = responseSpec.block();
return response.containsKey("password") && response.containsKey("provider");
}
PS。我也尝试过使用.exchangeToMono
而不是.retrieve
,这样我就可以检查响应状态代码,然后为.bodyToMono
函数使用不同的类型,但是一旦我在成功和失败之间编写了两种不同的类型,我就会收到一条错误消息,指出无法推断类型参数。
无法完全尝试您的代码,但请尝试以下操作:
public boolean updatePassword(String id, String data) {
final var responseSpec =
client
.post()
.uri(builder -> builder.path("/{id}/change_password").build(id))
.header(HttpHeaders.AUTHORIZATION, "Bearer " /*+ staticData.getAPIToken()*/)
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(data))
.retrieve()
.onStatus(
HttpStatus::isError,
error -> error.bodyToMono(ErrorResponse.class)
.map(errorResponse -> {
final var errorMsg = errorResponse.getCause().getSummary();
if (error.statusCode().is4xxClientError()) {
throw new HttpClientErrorException(error.statusCode(), errorMsg);
}
if (error.statusCode().is5xxServerError()) {
throw new HttpServerErrorException(error.statusCode(), errorMsg);
}
return new HttpServerErrorException(
HttpStatus.INTERNAL_SERVER_ERROR, "Something else.");
}))
.bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {});
final var response = responseSpec.block();
return response.containsKey("password") && response.containsKey("provider");
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句