我有两个模型: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。
但是,我必须验证经理和操作员的ID是否有效,这就是说,我将验证用户表中是否存在匹配的ID。
所以我想知道如何实施这种验证?
update1:使用验证器
这是创建新项目的形式:
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!");
}
}
看来此验证器有效。
但是,错误消息不能显示在窗体中。
然后通过调试我检查了结果对象,发现了这一点:
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
怎么修?
如何对Project进行验证? 是否有自定义验证程序? 您是否使用JSR-303验证?
没有验证者。 我不知道该怎么做。
有关验证的Spring文档应该给您一个入门
我已经读过tt,并且我知道如何验证Java类型的属性,但是不知道像我的示例那样的复杂类型的验证
这是一种可能的解决方案。
在下面创建类:
...
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
}
}
}
这应该使您入门。您可以以不同的方式实例化/设置验证器,有一个用户子验证器,但您已大致了解。
参考文献:
最新的Spring验证文档
此Stack Overflow帖子介绍了如何执行验证
我尝试按照您的步骤进行。 但是,它没有按我预期的那样工作。 你能检查我的更新吗? 谢谢。
errors.rejectValue("manager.id", ...)。由于项目对象容器另一个用户实例操作员也需要验证,因此我无法尝试。
那么,ProjectValidator应该可以解决问题。 另外,在控制器中仅调用一个验证器更为干净。 查看我编辑过的答案。
谢谢,我会尝试。
实际上,您需要做的是在@Valid上添加
private User manager;
private User operator;
像这样
@Valid
private User manager;
@Valid
private User operator;
在您的控制器中,您可以添加一个自定义验证器:
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setValidator(new ProjectValidator());
}
在此验证器中,您可以检查User对象或委托给UserValidator,如6.3节之前的最后一段中所述
我按照Jerome Dalbert的建议做了,此外还添加了一个自定义BeanValidator,用于将验证的实际工作委派给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 constraintViolation : constraintViolations) {
String propertyPath = constraintViolation.getPropertyPath().toString();
String message = constraintViolation.getMessage();
errors.rejectValue(prefix +"." + propertyPath,"", message);
}
}
public void validate(Object target, Errors errors) {
validate(target, errors,"");
}
}
这里是我在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");
}
}
参考文献:
http://blog.trifork.com/2009/08/04/bean-validation-integrating-jsr-303-with-spring/