在控制器中使用Spring MVC Validator使用多个域对象

时间:2014-03-04 09:33:03

标签: java spring validation spring-mvc url-routing

我有一个Spring MVC控制器来处理用户管理请求,包括保存用户详细信息的方法和允许用户重置密码的方法。我想使用验证器来确保用户输入两次相同的密码。

我的控制器

@Controller
public class UserDetails {
...
@InitBinder
public void binder(WebDataBinder binder) {
    binder.addValidators(new PasswordValidator());
}
...
@RequestMapping(value="/saveUserDetails", method=RequestMethod.POST)
public String saveUserDetails(
    @ModelAttribute User user) {
    ...
}
...
@RequestMapping(value="/resetPassword", method=RequestMethod.POST)
public String resetPassword(
    @Validated PasswordPair password, BindingResult result) {
    ...
}

验证器

    private final static class PasswordValidator implements Validator {

    private final static int MIN_LEN=5;

    @Override
    public boolean supports(Class<?> clazz) {
        return PasswordPair.class.isAssignableFrom(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        PasswordPair pair = (PasswordPair)target;
        //1 impose password rules
        if (pair.getPassword().length()<MIN_LEN) {
            errors.rejectValue("password", "Too short", "Password must bne at least "+MIN_LEN+" chars");
        }
        if (!pair.getPassword().equals(pair.getConfirmPassword())) {
            errors.rejectValue("confirmPassword", "mustMatch", "passwords must match");
        }
    }

  }

问题是当调用saveUserDetails时,spring正在尝试使用密码验证器验证用户。

我尝试将@InitBinder更改为@InitBinder("password")@InitBinder("PasswordPair"),但在这种情况下,根本不会对任何内容进行验证。

如何让它只验证正确的参数?

2 个答案:

答案 0 :(得分:4)

您使用@InitBinder(withname)的方法应该有效,我的猜测是您提供了错误的名称。

你能试试这个名字吗?

@InitBinder("passwordPair")

另一种选择是以这种方式明确地为您的ModelAttribute提供名称,并在InitBinder中使用该名称:

public String resetPassword(
    @ModelAttribute("password") @Valid PasswordPair password, BindingResult result) {
    ...
}

@InitBinder("password")

在相关的说明中,我在Spring Jira中记录了类似的问题,并且有一个拉取请求来更改此行为。如果可能,请将其投票 - https://jira.springsource.org/browse/SPR-11429

答案 1 :(得分:2)

将Password和confirmPassword字段添加到User对象,而不是使用PasswordPair对象。更改resetPassword方法以将用户设置为参数。 并更改验证程序以验证用户。在这里,我想即使在创建新用户时也会进行密码验证?

例如:

 @Controller
 public class UserDetails {

 @InitBinder
 public void binder(WebDataBinder binder) {
    binder.addValidators(new PasswordValidator());
 }

 @RequestMapping(value="/saveUserDetails", method=RequestMethod.POST)
 public String saveUserDetails(@ModelAttribute User user) {
    ...
 }

 @RequestMapping(value="/resetPassword", method=RequestMethod.POST)
 public String resetPassword(@Valid @ModelAttribute User user, BindingResult result) {
    ...
 }

验证器

private final static class UserValidator implements Validator {

private final static int MIN_LEN=5;

@Override
public boolean supports(Class<?> clazz) {
    return PasswordPair.class.isAssignableFrom(clazz);
}

@Override
public void validate(Object target, Errors errors) {
    User user = (User)target;
    //1 impose password rules
    if (user.getPassword().length()<MIN_LEN) {
        errors.rejectValue("password", "Too short", "Password must bne at least "+MIN_LEN+" chars");
    }
    if (!user.getPassword().equals(user.getConfirmPassword())) {
        errors.rejectValue("confirmPassword", "mustMatch", "passwords must match");
    }
  }

}

或者你可以查看这篇文章,也许它会帮助你:

Handling password confirmations on spring-mvc