2012-09-03 7 views
4

У меня есть две модели: User,ProjectSpring MVC вложенная модель проверки

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.

Однако я должен проверить идентификатор менеджера, и оператор действителен, то есть я буду проверять это, если в таблице пользователя есть сопоставленный идентификатор.

Итак, я хочу знать, как реализовать такую ​​валидацию?


update1: с помощью валидатора

Это форма для создания нового проекта:

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

кажется, что этот валидатор работает.

Однако сообщение об ошибке не может быть отображено в форме.

Тогда хотя отладки я инспектировать объект результата, и я нашел это:

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

Как исправить?

+0

Как вы выполнить проверку для 'project'? Есть ли специальный валидатор? Используете ли вы проверку JSR-303? – Pao

+0

нет валидатор. Я понятия не имею, как это сделать. – hguser

+0

[Spring doc on validation] (http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/validation.html) должен дать вам начало – Pao

ответ

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

     ... 
    } 
} 

И в контроллере сделать что-то вроде:

... 
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 
     } 
    } 

} 

Это должно вам начать работу. Вы можете создавать/устанавливать валидатор по-разному, иметь пользовательский суб-валидатор, но вы получаете общую идею.

Ссылки:

+0

Я пробовал следовать вашему шагу. Однако он не работает, как я ожидал. Можете ли вы проверить мое обновление? Благодарю. – hguser

+0

'errors.rejectValue (" manager.id ", ...)' .I не могу попробовать это, так как объект объекта-объекта представляет собой другой экземпляр-оператор пользователя, который также нуждается в проверке. – hguser

+0

Ну, тогда ProjectValidator должен сделать трюк. Кроме того, чистнее вызывать только один валидатор в контроллере. Проверьте мой отредактированный ответ. –

1

В вашем контроллере вы можете добавить пользовательский валидатор:

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

В этом валидатор, вы можете проверить User объекты или делегировать UserValidator, как это было сделано here в последнем абзаце до раздела 6.3

0

Я сделал то, что предложил Джером Dalbert и дополнительно добавлены пользовательские BeanValidator для делегирования фактической работы по проверке на 303 реализации JSR.

Префикс используется для обозначения пути свойства в форме.

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

и здесь, как я использовал его в 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"); 
} 
} 

Ссылки:

2

На самом деле то, что вам нужно сделать, это добавить @Valid на

private User manager; 
private User operator; 

как этот

@Valid 
private User manager; 
@Valid 
private User operator; 
Смежные вопросы