Spring Bean验证@Valid处理

时间:2014-07-17 19:11:54

标签: java spring-mvc bean-validation

我使用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永远不会被调用。

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

我知道我可以像下面那样重写,从注入的ConstraintViolation中获取Validator s的集合,但上面看起来更整洁......

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

2 个答案:

答案 0 :(得分:22)

我认为更好的方法是使用ExceptionHandler

Controller中,您可以编写ExceptionHandler来处理不同的例外情况。以下是相同的代码:

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

当您向Controller发送错误请求时,验证程序会抛出MethodArgumentNotValidException类型的异常。所以理想的方法是编写一个异常处理程序来专门处理这个异常。

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

<强>更新

当您对Controller中的方法参数使用@Valid注释时,会自动调用验证程序并尝试验证该对象,如果该对象无效,则会抛出MethodArgumentNotValidException

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

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

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

答案 1 :(得分:4)

试试这个

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