春豆验证@Valid处理

2022-09-03 09:11:42

我使用以下方法使用Bean Validation 1.2创建了一个Spring MVC REST服务:

@RequestMapping(value = "/valid")
public String validatedMethod(@Valid ValidObject object) {

}

如果对象无效,Tomcat 会通知我,并且我的永远不会被调用。The request sent by the client was syntactically incorrect.validatedMethod

如何获取在 Bean 中定义的消息?我应该使用一些过滤器还是拦截器?ValidObject

我知道我可以像下面这样重写,从注入中获取s的集合,但上面似乎更整洁...ConstraintViolationValidator

@RequestMapping(value = "/valid")
public String validatedMethod(ValidObject object) {
    Set<ConstraintViolation<ValidObject>> constraintViolations = validator
            .validate(object);
    if (constraintViolations.isEmpty()) {
        return "valid";
    } else {
        final StringBuilder message = new StringBuilder();
        constraintViolations.forEach((action) -> {
            message.append(action.getPropertyPath());
            message.append(": ");
            message.append(action.getMessage());
        });
        return message.toString();
    }
}

答案 1

我相信更好的方法是使用 .ExceptionHandler

在你可以写来处理不同的异常。以下是相同的代码:ControllerExceptionHandler

@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ValidationFailureResponse validationError(MethodArgumentNotValidException ex) {
    BindingResult result = ex.getBindingResult();
    final List<FieldError> fieldErrors = result.getFieldErrors();

    return new ValidationFailureResponse((FieldError[])(fieldErrors.toArray(new FieldError[fieldErrors.size()])));
}

当您向控制器发送错误请求时,验证程序会引发类型为 的异常。因此,理想的方法是编写一个异常处理程序来专门处理此异常。MethodArgumentNotValidException

在那里,您可以创建一个漂亮的响应,以告诉用户出错的事情。我提倡这样做,因为你只需要写一次,许多方法都可以使用它。:)Controller

更新

当您将 @Valid 注释用于 中的方法参数时,将自动调用验证程序并尝试验证对象,如果对象无效,则会引发 。ControllerMethodArgumentNotValidException

如果 Spring 找到此异常的方法,它将执行此方法中的代码。ExceptionHandler

您只需要确保控制器中存在上述方法即可。

现在还有另一种情况,当您有多个 s 想要验证方法参数时。在这种情况下,我建议你创建一个类,并将此方法放在那里。让你的 s 扩展这个类,你的工作就完成了。ControllerExceptionResolverController


答案 2

试试这个

@RequestMapping(value = "/valid")
public String validatedMethod(@Valid ValidObject object, BindingResult result) {
    StringBuilder builder = new StringBuilder();
    List<FieldError> errors = result.getFieldErrors();
    for (FieldError error : errors ) {
       builder.append(error.getField() + " : " + error.getDefaultMessage());
    } 
    return builder.toString();
}

推荐