spring mvc嵌套模型validation
我有两个模型: User,Project
public class Project{ private int id; @NotEmpty(message="Project Name can not be empty") private String name; private User manager; private User operator; //getter/setter omitted } public class User{ private int id; private String name; //omit other properties and getter/setter }
现在,当我创建一个新项目时,我将向ProjectController提交以下参数:
projects?name=jhon&manager.id=1&operator.id=2...
然后我将创建一个新的Project对象并将其插入到db。
但是我必须validation管理器的id和运算符是否有效,也就是说如果用户表中存在匹配的id,我将validation它。
所以我想知道如何实现这种validation?
update1:使用validation器
这是创建新项目的表单:
Manager:
Operator:
Name:
@Override public void validate(Object obj, Errors errors) { User user = (User) obj; int id=user.getId(); User u=userDao.query(id); if(u==null){ errors.rejectValue("id", "user does not exist!"); } }
看来这个validation器有效。
但是,错误消息无法在窗体中显示。
然后通过调试我检查结果对象,我发现了这个:
org.springframework.validation.BeanPropertyBindingResult: 2 errors Field error in object 'project' on field 'id': rejected value [0]; codes [user does not exist!.project.id,user does not exist!.id,user does not exist!.int,user does not exist!]; arguments []; default message [null] Field error in object 'project' on field 'id': rejected value [0]; codes [user does not exist!.project.id,user does not exist!.id,user does not exist!.int,user does not exist!]; arguments []; default message [null]
似乎结果确实有错误,但它的路径是project.id
而在我的表单中它是project.manager.id
怎么修?
这是一种可能的解决方案。
创建以下类:
... import org.springframework.validation.Validator; ... @Component public class ProjectValidator implements Validator { @Override public boolean supports(Class> clazz) { return Project.class.equals(clazz); } @Override public void validate(Object target, Errors errors) { Project project = (Project) target; /* Do your checks here */ ... if (managerIdDoesNotMatch) { errors.rejectValue("manager.id", "your_error_code"); } ... if (operatorIdDoesNotMatch) { errors.rejectValue("operator.id", "your_error_code"); } ... } }
在您的控制器中执行以下操作:
... public class ProjectController { @Autowired ProjectValidator projectValidator; ... @RequestMapping(...) public String yourCreateMethod(..., @ModelAttribute @Valid Project project, BindingResult result) { projectValidator.validate(project, result); if (result.hasErrors()){ // do something } else { // do something else } } }
这应该让你开始。 您可以以不同方式实例化/设置validation器,拥有一个用户子validation器,但您可以获得一般的想法。
参考文献:
- 最新的Springvalidation文档
- 此Stack Overflowpost介绍了如何执行validation
实际上你需要做的是添加@Valid
private User manager; private User operator;
喜欢这个
@Valid private User manager; @Valid private User operator;
在Controller中,您可以添加自定义validation器:
@InitBinder protected void initBinder(WebDataBinder binder) { binder.setValidator(new ProjectValidator()); }
在此validation器中,您可以检查User
对象或委托给UserValidator
,如6.3节前面的最后一段所述
我做了Jerome Dalbert建议的内容,另外添加了一个自定义BeanValidator,用于将validation的实际工作委托给JSR 303实现。
前缀用于表示表单中属性的路径。
@Component public class BeanValidator implements org.springframework.validation.Validator, InitializingBean { private Validator validator; public void afterPropertiesSet() throws Exception { ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); validator = validatorFactory.usingContext().getValidator(); } public boolean supports(Class clazz) { return true; } public void validate(Object target, Errors errors, String prefix) { Set> constraintViolations = validator.validate(target); for (ConstraintViolation
在这里我如何在UserValidator中使用它:
@Component public class UserValidator implements Validator { @Autowired BeanValidator beanValidator; @Override public boolean supports(Class> clazz) { return User.class.equals(clazz); } @Override public void validate(Object target, Errors errors) { User user = (User) target; beanValidator.validate(user.getAddress(), errors, "address"); } }
参考文献: