簡體   English   中英

在啟動 spring 引導應用程序時獲取為 MethodArgumentNotValidException 映射的不明確的 @ExceptionHandler 方法

[英]Getting Ambiguous @ExceptionHandler method mapped for MethodArgumentNotValidException while startup of spring boot application

我已經為我的 spring 控制器之一編寫了自定義異常處理程序 class,以驗證請求參數中的 email 屬性的格式是否正確。 因此創建了一個新的 class,它擴展了ResponseEntityExceptionHandler class 並使用@ExceptionHandler編寫了一個方法。

但是在 spring 啟動應用程序啟動期間,我遇到異常,停止運行我的項目。 有人可以幫我解決這個問題嗎?

服務器啟動時異常:

org.springframework.beans.factory.BeanCreationException:在 class 路徑資源 [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class] 中創建名稱為“handlerExceptionResolver”的 bean 時出錯:通過工廠方法實例化 Bean 失敗;
嵌套異常是 org.springframework.beans.BeanInstantiationException:無法實例化 [org.springframework.web.servlet.HandlerExceptionResolver]:工廠方法 'handlerExceptionResolver' 拋出異常;
nested exception is java.lang.IllegalStateException: Ambiguous @ExceptionHandler method mapped for [class org.springframework.web.bind.MethodArgumentNotValidException]: {public com.TestVO com.handler.exception.TestExceptionHandler.methodArgumentNotValidException(org.springframework.web.bind .MethodArgumentNotValidException), public final org.springframework.http.ResponseEntity org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException(java.lang.Exception,org.springframework.web.Webquests.Webquests.requests) java.lang.Exception}

自定義 Class 來處理MethodArgumentNotValidException

@ControllerAdvice
public class ExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public ErrorVO processValidationError(MethodArgumentNotValidException ex) {
        BindingResult result = ex.getBindingResult();
        List<FieldError> fieldErrors = result.getFieldErrors();
        FieldError fieldError = fieldErrors.get(0);
        ErrorVO dto = new ErrorVO(fieldError.getDefaultMessage());
        return dto;
    }
}

歧義是因為您在兩個類中都有相同的方法 - @ExceptionHandler - ResponseEntityExceptionHandler、MethodArgumentNotValidException。 您需要編寫如下重寫的方法來解決這個問題 -

   @Override
   protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
                 HttpHeaders headers, HttpStatus status, WebRequest request) {
          String errorMessage = ex.getBindingResult().getFieldErrors().get(0).getDefaultMessage();
          List<String> validationList = ex.getBindingResult().getFieldErrors().stream().map(fieldError->fieldError.getDefaultMessage()).collect(Collectors.toList());
          LOGGER.info("Validation error list : "+validationList);
          ApiErrorVO apiErrorVO = new ApiErrorVO(errorMessage);
          apiErrorVO.setErrorList(validationList);
          return new ResponseEntity<>(apiErrorVO, status);
   }

您在這里遇到的問題是意料之中的。 您正在有效地擴展 Spring ResponseEntityExceptionHandler ,默認情況下它已經在它自己的@ExceptionHandler注釋中包含MethodArgumentNotValidException的聲明。

您可以從類的來源輕松檢查這一點:

https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java

這就是您在日志中看到此錯誤的原因:

java.lang.IllegalStateException: Ambiguous @ExceptionHandler method mapped for [class org.springframework.web.bind.MethodArgumentNotValidException]

基於以上所有內容,您應該刪除自己的異常處理程序方法並覆蓋其中的方法。

Spring 有一個內置的ResponseEntityExceptionHandler用於MethodArgumentNotValidException 因此,對於同一異常,您有兩個處理程序,這是不允許的。

您可以嘗試覆蓋ResponseEntityExceptionHandler.handleMethodArgumentNotValid()

我找到了解決這個問題的方法!

我將 @ControllerAdvice 注釋更改為 @RestControllerAdvice for Rest controller。

Spring 引導和 ControllerAdvice 結構已包含 MethodArgumentNotValidException。 然后我通過 intellij idea /或不同的 ide 調用覆蓋方法來覆蓋默認情況下出現的 MethodArgumentNotValidExcetion function。

它成功地工作::) 希望它能幫助你! :)

例子

@Override
@ResponseStatus
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {

    for (ObjectError methodArgumentNotValidException : ex.getBindingResult().getAllErrors()){
        localerrorEntitiesList.add(new ErrorEntity(methodArgumentNotValidException.getDefaultMessage(),methodArgumentNotValidException.getCode()));
    }

    try {
        return new ResponseEntity<>(new ErrorResponse(localerrorEntitiesList),HttpStatus.BAD_REQUEST);
    }catch (Exception e){
        return new ResponseEntity<>(new ErrorResponse(localerrorEntitiesList),HttpStatus.BAD_REQUEST);
    }

}

暫無
暫無

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

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