[英]HTTP Response Exception Handling in Spring 5 Reactive
I'm developing some reactive microservices using Spring Boot 2 and Spring 5 with WebFlux reactive starter. 我正在使用Spring Boot 2和Spring 5开发一些带有WebFlux反应启动器的反应式微服务。
I'm facing the following problem: I want to handle all HTTP Statuses that I receive from calling another REST Services and throws an exception when I receive some bad HTTP Status. 我遇到了以下问题:我想处理从调用另一个REST服务收到的所有HTTP状态,并在收到一些错误的HTTP状态时抛出异常。 For example, when I call an endpoint and I receive an 404 HTTP Status, I want to throw an exception and that exception to be handled in some ExceptionHandler class, just like the way it was in Spring 4 with
@ControllerAdvice
. 例如,当我调用端点并收到404 HTTP状态时,我想抛出一个异常,并在一些ExceptionHandler类中处理该异常,就像在Spring 4中使用
@ControllerAdvice
。
What is the right way to do this? 这样做的正确方法是什么? Hope to receive some good suggestions.
希望收到一些好的建议。
This can be addressed in two independent parts. 这可以通过两个独立的部分来解决。
When using WebClient
, you can receive HTTP 404 responses from remote services. 使用
WebClient
,您可以从远程服务接收HTTP 404响应。 By default, all 4xx
and 5xx
client responses will be turned into WebClientResponseException
. 默认情况下,所有
4xx
和5xx
客户端响应都将变为WebClientResponseException
。 So you can directly handle those exceptions in your WebFlux app. 因此,您可以直接在WebFlux应用程序中处理这些异常。
If you'd like to turn only 404 responses into custom exceptions, you can do the following: 如果您只想将404响应转换为自定义例外,则可以执行以下操作:
WebClient webClient = //...
webClient.get().uri("/persons/1")
.retrieve()
.onStatus(httpStatus -> HttpStatus.NOT_FOUND.equals(httpStatus),
clientResponse -> Mono.error(new MyCustomException()))
.bodyToMono(...);
This is obviously done on a per client call basis. 这显然是基于每个客户呼叫完成的。
You can achieve the same in a more reusable way with an ExchangeFilterFunction
that you can set once and for all on a WebClient
instance like this: 您可以使用
ExchangeFilterFunction
以更可重用的方式实现相同的功能,您可以在WebClient
实例上一劳永逸地设置,如下所示:
WebClient.builder().filter(myExchangeFilterFunction)...
With Spring WebFlux with annotations, you can handle exceptions with methods annotated with @ExceptionHandler
(see Spring Framework reference documentation ). 随着春天WebFlux与注释,您可以处理与注解的方法例外
@ExceptionHandler
(见Spring Framework的参考文档 )。
Note: using a WebExceptionHandler
is possible, but it's quite low level as you'll have no high-level support there: you'll need to manually write the response with buffers without any support for serialization. 注意:使用
WebExceptionHandler
是可能的,但它的级别很低,因为你没有高级支持:你需要手动编写带缓冲区的响应,而不需要任何序列化支持。
I think what you are looking for is WebFluxResponseStatusExceptionHandler
the check this for reference . 我认为你要找的是
WebFluxResponseStatusExceptionHandler
检查这个以供参考 。
In the WebHandler API, a WebExceptionHandler can be used to to handle exceptions from the chain of WebFilter's and the target WebHandler.
在WebHandler API中,WebExceptionHandler可用于处理来自WebFilter链和目标WebHandler的异常。 When using the WebFlux Config, registering a WebExceptionHandler is as simple as declaring it as a Spring bean, and optionally expressing precedence via @Order on the bean declaration or by implementing Ordered.
使用WebFlux配置时,注册WebExceptionHandler就像将其声明为Spring bean一样简单,并可选择通过bean声明上的@Order或通过实现Ordered来表示优先级。
This example may help, have not tried it myself. 这个例子可能有所帮助,我自己没试过。
@Component
@Order(-2)
class RestWebExceptionHandler implements WebExceptionHandler{
@Override
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
if (ex instanceof PostNotFoundException) {
exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
// marks the response as complete and forbids writing to it
return exchange.getResponse().setComplete();
}
return Mono.error(ex);
}
}
class PostNotFoundException extends RuntimeException {
PostNotFoundException(String id) {
super("Post:" + id + " is not found.");
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.