我正在编写一个使用 Spring Cloud Gateway MVC 构建的 API Gateway 应用程序。我使用了一个自定义的 CircuitBreaker 过滤器,该过滤器可在后端请求耗时过长时超时。
我发现当请求超时时......我无法通过向客户端发送 JSON 格式的响应来优雅地处理失败。
我拥有带有 ExceptionHandler 方法的自定义 ControllerAdvice Bean,这些方法似乎无法拦截 Gateway MVC 过滤器中的任何故障。当故障发生在 GatewayMVC 筛选器之外(如无法找到匹配的路由等)时,异常处理可完美运行。
ControllerAdvice Bean 是否应处理 GatewayFilter 故障?我们拥有的是 RouterFunctions,而不再是 MVC 控制器。
Any guidance on ExceptionHandling for SpringGatewayMVC?
感谢您的帮助。
ControllerAdvice Bean 不处理 GatewayFilter 异常。
这是因为 GatewayFilter 在 Spring Web MVC 的 DispatcherServlet 之前 运行。ControllerAdvice 异常处理机制是 Spring Web MVC 的一部分,并且仅处理 DispatcherServlet 处理请求期间抛出的异常。
为 Spring Cloud Gateway MVC 处理异常的解决方案:
-
使用 GatewayFilter 中的
one rrorResume
操作符: -
在你的自定义 CircuitBreaker GatewayFilter 中,使用
one rrorResume
操作符捕获超时异常。 -
在
one rrorResume
回调中,构造并返回一个带有 JSON 错误响应的Mono<Response>>
对象。
```java @Component public class CustomCircuitBreakerFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange)
.timeout(Duration.ofMillis(500)) // 设置超时时间
.onErrorResume(TimeoutException.class,
ex -> Mono.just(ResponseEntity.status(HttpStatus.GATEWAY_TIMEOUT)
.body(Collections.singletonMap("error", "Request timeout"))));
}
@Override
public int getOrder() {
return -1; // 在其他过滤器之前执行
}
} ```
-
使用 Spring Cloud Gateway 的全局错误处理:
-
创建一个实现
ErrorWebExceptionHandler
接口的 Bean。 -
在
handle()
方法中,检查异常类型并返回自定义的 JSON 错误响应。
```java @Component public class JsonExceptionHandler implements ErrorWebExceptionHandler {
@Override
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
if (ex instanceof TimeoutException) {
// 处理超时异常
exchange.getResponse().setStatusCode(HttpStatus.GATEWAY_TIMEOUT);
// ... 设置 JSON 响应体
} else {
// 处理其他异常
}
return Mono.empty();
}
// ... 其他必需的方法
} ```
注意:
要启用全局错误处理,需要在 Spring 配置中将
ErrorWebExceptionHandler
Bean 注册为主要 Bean。
通过这两种方法,可以在 Spring Cloud Gateway MVC 应用程序中优雅地处理超时和其他异常,并向客户端返回 JSON 错误响应。
标签:spring-mvc,exception,error-handling,spring-cloud,spring-cloud-gateway From: 78295133