Spring MVC和JSR-303休眠条件验证
-
26-09-2019 - |
题
我一个形式我想验证。它包含2个地址变量。地址1一直被验证,地址2具有基于一些条件进行验证
public class MyForm {
String name;
@Valid Address address1;
Address address2;
}
public class Address {
@NotEmpty
private String street;
}
我的控制器自动验证和结合我的形式OBJ
@RequestMapping(...)
public ModelAndView edit(
@ModelAttribute("form")
@Valid
MyForm form,
BindingResult bindingResult,
...)
if(someCondition) {
VALIDATE form.address2 USING JSR 303
的问题是,如果我使用LocalValidatorFactoryBean验证我不能重用Spring提供的BinidingResult对象。绑定不会工作作为“结果”的目标对象是“MyForm的”,而不是“地址”
validate(form.getAddress2(), bindingResult) //won't work
我不知道有什么标准/清洁方法进行条件验证。
我想在编程创建我的控制器新BindingResult。
final BindingResult bindingResultAddress2 = new BeanPropertyBindingResult(address2, "form");
validate(form.getAddress2(), bindingResultAddress2);
但随后的错误我从bindingResultAddress2获取列表不能被添加到一般的“bindingResult”作为字段名是不正确(“街道”,而不是“address2.street”)和结合不会工作
有些脏的方法是延长BeanPropertyBindingResult接受一些字符串追加到字段名..你有更好的方法吗?
解决方案
有关验证层次结构的标准方法是使用pushNestedPath()
/ popNestedPath()
,虽然我不知道它是如何发挥与JSR-303:
bindingResult.pushNestedPath("address2");
validate(form.getAddress2(), bindingResult);
bindingResult.popNestedPath();
其他提示
我从来没有尝试过自己,但我认为正确的做法是使用的验证组。
首先,让我们来看看 @ javax.validation.Valid API
<强>标记的关联作为级联即可。相关的对象将通过级联进行验证。
当Spring框架使用@Valid的作为标记以验证其命令对象,它破坏了目的。春节应改为创建自己的特定注释指定哪个应验证的组。
不幸的是,你应该,如果你需要验证某些群体使用Spring本地验证API
public void doSomething(Command command, Errors errors) {
new BeanValidationValidator(SomeUserCase.class, OtherUserCase.class)
.validate(command, errors);
if(errors.hasErrors()) {
} else {
}
}
BeanValidationValidator可以实现为
public class BeanValidationValidator implements Validator {
javax.validation.Validator validator = ValidatorUtil.getValidator();
private Class [] groups;
public BeanValidationValidator(Class... groups) {
this.groups = groups;
}
public void validate(Object command, Errors errors) {
Set<ConstraintViolation<Object>> constraintViolationSet = validator.validate(command, groups);
for(ConstraintViolation<Object> constraintViolation: constraintViolationSet) {
errors.rejectValue(constraintViolation.getPropertyPath().toString(), null, constraintViolation.getMessage());
}
}
}
不隶属于 StackOverflow