在春季启动应用程序启动时获取为MethodArgumentNotValidException映射的模糊@ExceptionHandler方法

时间:2018-08-23 18:17:38

标签: java spring spring-boot exceptionhandler

我为我的一个spring控制器编写了自定义异常处理程序类,以验证来自请求参数的电子邮件属性是否采用正确的格式。因此,创建了一个扩展ResponseEntityExceptionHandler类的新类,并使用@ExceptionHandler编写了一个方法。

但是在春季启动应用程序启动期间,我遇到了以下异常,该异常正在停止运行我的项目。有人可以帮我解决这个问题吗?

服务器启动期间的异常:

  

org.springframework.beans.factory.BeanCreationException:在类路径资源[org / springframework / boot / autoconfigure / web / servlet / WebMvcAutoConfiguration $ EnableWebMvcConfiguration.class]中创建名称为'handlerExceptionResolver'的bean时出错:通过工厂实例化Bean方法失败;
  嵌套的异常是org.springframework.beans.BeanInstantiationException:无法实例化[org.springframework.web.servlet.HandlerExceptionResolver]:工厂方法'handlerExceptionResolver'引发了异常;
  嵌套异常是java.lang.IllegalStateException:为[类org.springframework.web.bind.MethodArgumentNotValidException]映射的模糊@ExceptionHandler方法:{public com.TestVO com.handler.exception.TestExceptionHandler.methodArgumentNotValidException(org.springframework.web.bind .MethodArgumentNotValidException),公共最终org.springframework.http.ResponseEntity org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException(java.lang.Exception,org.springframework.web.context.request.WebRequest)抛出java.lang.Exception}

要处理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;
    }
}

3 个答案:

答案 0 :(得分:3)

模棱两可是因为您在两个类(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);
   }

答案 1 :(得分:0)

Spring为ResponseEntityExceptionHandler内置了MethodArgumentNotValidException。因此,对于同一个不允许的异常,您有两个处理程序。

您可以尝试覆盖ResponseEntityExceptionHandler.handleMethodArgumentNotValid()

答案 2 :(得分:0)

您在这里遇到的问题是可以预期的。您正在有效地扩展Spring ResponseEntityExceptionHandler,默认情况下,Spring MethodArgumentNotValidException在其自己的@ExceptionHandler注释中已经包含java.lang.IllegalStateException: Ambiguous @ExceptionHandler method mapped for [class org.springframework.web.bind.MethodArgumentNotValidException] 的声明。

您可以轻松地从课程的源代码中进行检查:

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

这就是为什么您在日志中看到此错误的原因:

#set($ids = [])
#foreach($id in ${ctx.args.bookID})
    #set($map = {})
    $util.qr($map.put("id", $util.dynamodb.toString($id)))
    $util.qr($ids.add($map))
#end

{
    "version" : "2018-05-29",
    "operation" : "BatchGetItem",
    "tables" : {
        "Books": {
            "keys": $util.toJson($ids),
            "consistentRead": true
        }
    }
}

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