【问题标题】:Spring Webflux ErrorHandling - @RestControllerAdvice with @ExceptionHandler or DefaultErrorAttributes?Spring Webflux ErrorHandling - @RestControllerAdvice 与 @ExceptionHandler 或 DefaultErrorAttributes?
【发布时间】:2019-08-12 20:48:08
【问题描述】:

Spring Webflux中,首选的异常处理方式是什么?

@RestControllerAdvice 来自 Spring MVC 而 DefaultErrorAttributes 来自 Spring Webflux。

然而,在 Spring Webflux 中有人可以使用 @RestControllerAdvice。有什么优点/缺点?

@RestControllerAdvice

@RestControllerAdvice
public class ControllerAdvice
{
    @ExceptionHandler(Throwable.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Mono<Map<String, Object>> exceptions(Throwable e)
    {
        return Mono.just(Map.of("message", "bad"));
    }
}

扩展 DefaultErrorAttributes

@Component
public class ErrorAttributes extends DefaultErrorAttributes
{
    @Override
    public Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace)
    {
        var ex = getError(request);

        var attributes = new LinkedHashMap<String, Object>();
        attributes.put("status", HttpStatus.BAD_REQUEST.value());
        attributes.put("message", "bad");

        return attributes;
    }
}

我想留在响应式世界中,所以我更倾向于 DefaultErrorAttributes(它与 Webflux 中的 DefaultErrorWebExceptionHandler 配合得很好)。但是,在@RestControllerAdvice 中,我也可以使用 Mono.just(...)。

【问题讨论】:

  • 我注意到它“已经有一段时间了”并且没有任何回应。这是因为它是“偏好的东西”吗?我对 Webflux 也很陌生,很高兴听到那些做这件事的人的来信(即,我相当确定扩展 DefaultErrorAttributes 是“一个附加选项”是有原因的" 在 Webflux 中)。

标签: spring spring-boot exception error-handling spring-webflux


【解决方案1】:

是一样的。像 WebMvc。

@RestControllerAdvice
public class ControllerAdvice {
    @ExceptionHandler(AnyException.class)
    public Mono<EntityResponse<YourModel>> example(AnyException exception) {
        return EntityResponse.fromObject(new YourModel()).status(HttpStatus.NOT_FOUND).build();
    }
}

【讨论】:

    【解决方案2】:

    在Spring Webflux中,如果功能路由声明,你也可以实现自己的ExceptionHandler而不是DefaultErrorWebExceptionHandler

        class SystemErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {
        @Override
        public Mono<Void> handle(ServerWebExchange exchange, Throwable throwable) {
            return super.handle(exchange, throwable)
                        // debug, process
                        .contextWrite(...);
        }
    
        @Override
        protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
            // for all routs
            return route(all(), this::renderErrorResponse);
        }
    
        private Mono<ServerResponse> renderErrorResponse(ServerRequest request) {
            Map<String, Object> error = getErrorAttributes(request, ErrorAttributeOptions.of());
            Throwable t = this.getError(request);
            // map exception on response
            return ServerResponse.status(status).body(...);
        }
    }
    

    然后使用 @AutoConfigureBefore(WebFluxAutoConfiguration.class) 在 spring 配置中使用 AbstractErrorWebExceptionHandler 的实现

    【讨论】:

      猜你喜欢
      • 2017-12-24
      • 2020-07-26
      • 2023-01-31
      • 1970-01-01
      • 2013-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-23
      相关资源
      最近更新 更多