簡體   English   中英

@RestControllerAdvice 在 Spring Boot 反應式 Java 應用程序中不起作用

[英]@RestControllerAdvice not working in Spring Boot reactive java application

我目前正在拋出一個自定義異常 - RequestValidationException

ExceptionHandler

@RestControllerAdvice
@Slf4j
public class RestExceptionHandler {

    @ExceptionHandler(value = RequestValidationException.class)
    @ResponseStatus(HttpStatus.PRECONDITION_FAILED)
    public Mono<HttpValidationError> handleRequestValidationException(RequestValidationException exception) {
        log.error("Received exception: ", exception);
        List<String> loc = new ArrayList<>();
        loc.add(exception.getMessage());
        ValidationError validationError = ValidationError.builder()
            .loc(loc)
            .msg(exception.getMessage())
            .build();
        List<ValidationError> errorMessages = new ArrayList<>();
        errorMessages.add(validationError);
        return Mono.just(HttpValidationError.builder().detail(errorMessages).build());
}

RequestValidationException

public class RequestValidationException extends RuntimeException {
    public static final HttpStatus statusCode = HttpStatus.PRECONDITION_FAILED;

    public RequestValidationException(String text) {
        super(text);
    }

    public HttpStatus getStatusCode() {
        return statusCode;
    }
}

exception被拋出,我想下面的response

 Code: 412
 {
    "detail": [
    {
       "loc": [
                "No ID found to update. Please add an ID"
       ],
       "msg": "No ID found to update. Please add an ID",
       "type": null
    }
  ]
}  

我收到的是:

{
  "error_code": 500,
  "message": "No ID found to update. Please add an ID"
}

我檢查了應用程序日志,沒有任何地方調用RestExceptionHandler 它只記錄此error

"level":"ERROR","logger":"c.a.c.c.c.AbstractController","thread":"boundedElastic-1","message":"Controller exception","stack":"<#384d845f> c.a.c.a.e.RequestValidationException

我似乎無法弄清楚這段代碼有什么問題。 有人可以指出我可能缺少什么嗎? 謝謝。

我只能讓它與AbstractErrorWebExceptionHandler的實現一起工作,如下所示(對不起 kotlin 代碼):

@Component
@Order(-2)
class GlobalExceptionHandler(errorAttributes: ErrorAttributes,
                             resources: WebProperties.Resources,
                             applicationContext: ApplicationContext,
                             serverCodecConfigurer: ServerCodecConfigurer) : AbstractErrorWebExceptionHandler(errorAttributes, resources, applicationContext) {

    companion object {
        private val logger = KotlinLogging.logger {}
        private const val HTTP_STATUS_KEY = "status"
        private const val MESSAGE_KEY = "message"
        private const val ERRORS_KEY = "errors"
    }

    init {
        setMessageWriters(serverCodecConfigurer.writers)
    }

    override fun setMessageWriters(messageWriters: MutableList<HttpMessageWriter<*>>?) {
        super.setMessageWriters(messageWriters)
    }

    override fun getRoutingFunction(errorAttributes: ErrorAttributes?): RouterFunction<ServerResponse> {
        return RouterFunctions.route({ true }) { request ->
            val error: Throwable = getError(request)
            logger.error("Handling: ", error)

            val errorProperties = getErrorAttributes(request, ErrorAttributeOptions.defaults())
            when (error) {
                is WebExchangeBindException -> {
                    ....
                }
                else -> {
                    ...
                }
            }

            ServerResponse.status(HttpStatus.valueOf(errorProperties[HTTP_STATUS_KEY] as Int))
                .contentType(MediaType.APPLICATION_JSON)
                .bodyValue(errorProperties)
        }
    }
}

在 Java 中,它類似於:

@Component
@Order(-2)
public class GlobalExceptionHandler extends AbstractErrorWebExceptionHandler {

   private static final String HTTP_STATUS_KEY = "status";
   private static final String MESSAGE_KEY = "message";
   private static final String ERRORS_KEY = "errors"; 

   public GlobalExceptionHandler(ErrorAttributes errorAttributes, Resources resources, ApplicationContext applicationContext, ServerCodecConfigurer serverCodecConfigurer) {
      super(errorAttributes, resources, applicationContext);
      this.setMessageWriters(serverCodecConfigurer.getWriters());
   }

   public final void setMessageWriters(List messageWriters) {
      super.setMessageWriters(messageWriters);
   }

   protected RouterFunction getRoutingFunction(ErrorAttributes errorAttributes) {
      return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
   }

   private Mono<ServerResponse> renderErrorResponse(ServerRequest request) {
       Map<String, Object> errorPropertiesMap = getErrorAttributes(request, 
         ErrorAttributeOptions.defaults());

       return ServerResponse.status(HttpStatus.BAD_REQUEST)
         .contentType(MediaType.APPLICATION_JSON)
         .body(BodyInserters.fromValue(errorPropertiesMap));
    }
}

您可以在https://www.baeldung.com/spring-webflux-errors#global查看更多詳細信息。

我犯了一個非常微不足道的錯誤,用AbstractController類擴展了controller ,這導致了這個問題。 刪除它解決了我的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM