我使用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();
}
}
答案 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();
}