在启动Spring Boot 应用程序时获取为MethodArgumentNotValidExceptionMap的Ambiguous @ExceptionHandler方法

iqxoj9l9  于 2022-11-28  发布在  Spring
关注(0)|答案(4)|浏览(337)

我已经为我的一个spring控制器编写了自定义异常处理程序类来验证来自请求参数的email属性是否是正确的格式。因此创建了一个新的类来扩展ResponseEntityExceptionHandler类,并使用@ExceptionHandler编写了一个方法。
但在Spring Boot 应用程序启动,我得到下面的异常是停止运行我的项目。有人能帮我解决这个问题吗?

服务器启动期间出现异常:

org.springframework.beans.factory.BeanCreationException:创建在类路径资源[org/springframework/ Boot /autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]中定义的名为“handlerExceptionResolver”的Bean时出错:通过工厂方法示例化Bean失败;
嵌套异常是一个嵌套的异常。无法示例化[org.springframework.web.servlet.HandlerExceptionResolver]:工厂方法“handlerExceptionResolver”引发了异常;
嵌套的异常是java.lang.IllegalStateException:为[类Map的@ExceptionHandler方法不明确。{在运行时,如果出现异常,则会引发一个异常。}
处理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;
    }
}
sr4lhrrt

sr4lhrrt1#

出现多义性是因为您在两个类(ResponseEntityExceptionHandler和MethodArgumentNotValidException)中具有相同的方法- @ExceptionHandler。您需要按如下所示编写重写的方法来解决此问题-

@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);
   }
to94eoyn

to94eoyn2#

您在这里遇到的问题是意料之中的,您实际上是在扩展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]

基于以上所有内容,您应该删除自己的异常处理程序方法,并覆盖其中的异常处理程序方法。

ljo96ir5

ljo96ir53#

Spring有一个内置的ResponseEntityExceptionHandler for MethodArgumentNotValidException。所以你有两个处理程序用于同一个异常,这是不允许的。
您可以尝试覆写ResponseEntityExceptionHandler.handleMethodArgumentNotValid()

esyap4oy

esyap4oy4#

我找到了解决这个问题的办法!
我将Rest控制器的@ControllerAdvice注解更改为@RestControllerAdvice。
Sping Boot 和ControllerAdvice结构已经包含MethodArgumentNotValidException。然后我通过intellij idea /或其他ide调用override方法来覆盖默认情况下提供的MethodArgumentNotValidExcetion函数。
而且它成功地工作了!:)希望它对你有帮助!:)
范例

@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);
    }

}

相关问题