Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java SpringMVC嵌套模型验证_Java_Spring_Validation_Spring Mvc - Fatal编程技术网

Java SpringMVC嵌套模型验证

Java SpringMVC嵌套模型验证,java,spring,validation,spring-mvc,Java,Spring,Validation,Spring Mvc,我有两种型号: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{ p

我有两种型号:
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…

然后,我将创建一个新的项目对象并将其插入db

但是,我必须验证经理和操作员的id是否有效,也就是说,我将验证用户表中是否有匹配的id

所以我想知道如何实现这种验证


更新1:使用验证器

这是创建新项目的表单:

<sf:form method="${project.id==0?'post':'put'}" commandName="project" action="${context}${action}">
    Manager:<sf:input path="manager.id" />  <sf:errors path="manager.id" /> <br />
    Operator:<sf:input path="operator.id" />    <sf:errors path="operator.id" />    <br />
    Name:<sf:input path="name" />   <sf:errors path="name" />   <br />
    <input type="submit" value="Submit" />
</sf:form>


@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!");
    }
}
结果似乎确实有错误,但它的路径是
project.id
,而在我的表单中它是
project.manager.id


如何修复?

在控制器中,您可以添加自定义验证器:

@InitBinder
protected void initBinder(WebDataBinder binder) {
    binder.setValidator(new ProjectValidator());
}

在此验证器中,您可以检查
用户
对象或委托给
用户验证器
,如第6.3节之前的最后一段所述,这里有一个可能的解决方案

在下面创建类:

...
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");
        }

        ...
    }
}
这应该让你开始。您可以以不同的方式实例化/设置验证器,使用一个用户子验证器,但您可以了解总体思路

参考资料:


我按照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<ConstraintViolation<Object>> constraintViolations = validator.validate(target);
  for (ConstraintViolation<Object> 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, "");
 }
}
@组件
公共类BeanValidator实现org.springframework.validation.Validator,初始化Bean{
私人验证器;
public void afterPropertieSet()引发异常{
ValidatorFactory=Validation.buildDefaultValidatorFactory();
validator=validatorFactory.usingContext().getValidator();
}
公共布尔支持(类clazz){
返回true;
}
公共无效验证(对象目标、错误、字符串前缀){
Set constraintViolations=validator.validate(目标);
for(ConstraintViolation ConstraintViolation:constraintViolations){
String propertyPath=constraintViolation.getPropertyPath().toString();
String message=constraintViolation.getMessage();
错误。拒绝值(前缀+“+”属性路径“”,消息);
}
}
公共无效验证(对象目标、错误){
验证(目标,错误,“”);
}
}
下面是我如何在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");
 }
}
@组件
公共类UserValidator实现验证器{
@自动连线
BeanValidator BeanValidator;
@凌驾
公共布尔支持(类clazz){
返回User.class.equals(clazz);
}
@凌驾
公共无效验证(对象目标、错误){
用户=(用户)目标;
验证(user.getAddress(),错误,“地址”);
}
}
参考资料:


实际上,您需要做的是在

private User manager;
private User operator;
像这样

@Valid
private User manager;
@Valid
private User operator;

如何对
项目执行验证?是否有自定义验证程序?您使用JSR-303验证吗?没有验证程序。我不知道怎么做。应该给你一个开始。我已经阅读了tt,我知道如何验证java类型的属性,但是我不知道复杂类型的验证,就像我的示例一样。我试着按照你的步骤。然而,它并没有像我预期的那样工作。你能查一下我的更新吗?谢谢。
errors.rejectValue(“manager.id”,…)
。我无法尝试此操作,因为项目对象容器还包含另一个需要验证的用户实例操作符。那么,ProjectValidator应该完成此操作。另外,只调用控制器中的一个验证器更干净。看看我编辑过的答案。
private User manager;
private User operator;
@Valid
private User manager;
@Valid
private User operator;