【问题标题】:Using Spring MVC Validator in controller using multiple domain objects在使用多个域对象的控制器中使用 Spring MVC Validator
【发布时间】:2014-03-04 09:33:03
【问题描述】:

我有一个 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"),但在这种情况下根本没有任何验证。

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

【问题讨论】:

  • 请提供 PasswordPair 的代码,谢谢。
  • 公共类 PasswordPair { 字符串密码;字符串确认密码; public String getPassword() { 返回密码; } public void setPassword(String password) { this.password = password; } 公共字符串 getConfirmPassword() { 返回确认密码; } public void setConfirmPassword(String confirmPassword) { this.confirmPassword = confirmPassword; } }
  • 请务必在 jsp 中提供代码。 :)
  • 我正在使用速度模板。 #set( $layout="templates/nolayout.vm" )

    重置密码

    密码 #springFormPasswordInput("passwordPair .password" "") #springShowErrors("
    " "")
    确认密码 #springFormPasswordInput("passwordPair.confirmPassword" "") #springShowErrors( "
    " "")
  • 正在更改为有效并使用 setValidator - 它仍在尝试将验证器应用于传递给 createUser 的用户对象

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


【解决方案1】:

您使用@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

【讨论】:

  • 谢谢大家。看起来传递给 InitBinder 的值必须与传递给 ModelAttribute 的值匹配。 IE。 @InitBinder("passwordPair")@ModelAttribute("passwordPair")
【解决方案2】:

将密码和确认密码字段添加到用户对象而不是密码对对象。更改 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

【讨论】:

  • 它仍在尝试将验证器应用于传递给 createUser 的用户对象
猜你喜欢
  • 2021-12-21
  • 1970-01-01
  • 2012-08-19
  • 2013-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-17
  • 1970-01-01
相关资源
最近更新 更多