首页 > 解决方案 > 是否可以为 @Valid 参数异常创建多个自定义验证消息?

问题描述

我想为我的自定义验证注释创建自定义消息。如果此验证失败,则会引发 MethodArgumentNotValidException。因为我为@RequestBody 设置了@Valid。

我创建 @ControllerAdvice 来处理/覆盖 MethodArgumentNotValidException 消息。我单独有这个枚举错误类。所以每个抛出这种异常的错误都会抛出相同的消息Invalid Param

我的问题是是否可以排除我的自定义验证消息并抛出不同的消息?如何使这个@MyCustomAnnotation 抛出不同的异常消息?不属于 MethodArgumentNotValidException 消息。

我的自定义验证界面

@Documented
@Constraint(validatedBy = myValidator.class)
@Target({FIELD, METHOD, ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckMyCode{
    String message() default "{my custom string message}";
    Class<?> [] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

我的控制器建议方法来处理所有 MethodArgumentNotValidException 异常

@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException exception, HttpHeaders headers, HttpStatus status, WebRequest request){
        CustomClassError<Object> error = CustomClassError.failure(ErrCode.INVALID_PARAM);
        return new ResponseEntity<Object>(error, new HttpHeaders(), HttpStatus.OK);
}

标签: javarestspring-bootconstraintsbean-validation

解决方案


您可以覆盖handleMethodArgumentNotValid控制器建议中的方法,例如(似乎这是您需要的用例):

@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
    List<String> details = new ArrayList<>();
    for(ObjectError error : ex.getBindingResult().getAllErrors()) {
        details.add(error.getDefaultMessage());
    }
    ErrorResponse error = new ErrorResponse("Validation Failed", details);
    return new ResponseEntity(error, HttpStatus.BAD_REQUEST);
}

或者,在您的控制器类中,您可以通过抛出自定义异常然后在控制器建议中单独处理它来处理它(不适用于验证异常,但对于所有其他运行时异常,这种方法更适合处理异常):

@PostMapping("/addValidate")
public String submitForm(@Valid ValidatedData validatedData,
  BindingResult result, Model m) {
    if(result.hasErrors()) {
         List<FieldError> errors = bindingResult.getFieldErrors(); // provided only for your information
         for (FieldError error : errors ) {
             System.out.println (error.getObjectName() + " - " +error.getDefaultMessage());
          }
        throw new CustomExceptionClass("Your could assign the field error custom message here");
    }
    m.addAttribute("message", "Success"
      + validatedData.toString());
    return "Home";
} 

然后在您的控制器建议类中,您可以使用此消息传递给异常,例如:

@ExceptionHandler(Exception.class)
public final ResponseEntity<Object> handleAllExceptions(Exception ex, WebRequest request) {
    List<String> details = new ArrayList<>();
    details.add(ex.getLocalizedMessage()); //just call the message method to get the message in the exception
    ErrorResponse error = new ErrorResponse("Server Error", details); //Custom error response class to return json response
    return new ResponseEntity(error, HttpStatus.INTERNAL_SERVER_ERROR);
}

推荐阅读