Spring:相同的对象,不同的验证

时间:2010-03-18 09:25:51

标签: validation spring

我有一个名为User的对象,我保存了User的所有数据。我有一些注释来执行验证,它工作正常。

public class User{
    @NotEmpty
    @Email
    @Size(max=100)
    @Column(name="username", length=100, nullable=false, unique=true)
    private String username;

    @NotEmpty
    @Size(min=5, max=40)
    @Column(name="password", length=40, nullable=false)
    private String password;

    @Size(min=5, max=40)
    @Transient
    private String newPassword;

    // other attributes ,getters and setters
 }

我有两种不同的形式(每种形式在不同的页面中)。在第一个我要求用户名和密码来创建用户,所以这两个都是强制性的。

在第二种形式中,我显示了有关用户的信息:用户名,其他数据(也将进行验证)以及密码和newPassword。如果设置了newPassword并且密码与用户的密码相同,我将更改用户的密码,但如果它们为空,则表示我不应更改密码。

问题是我有两个与同一个对象相关的表单,其中对字段密码进行了不同的验证。在第一个中它必须不是空的,但在第二个中它可以是空的。

在控制器中,我以这种方式验证对象:

public String getUserDetails(@Valid @ModelAttribute("User") User user, BindingResult result, Model model){
    if(result.hasErrors()){
        //There have been errors
    }
    ...
}

但是密码为空会出错。

有没有办法只在对象的某些字段中执行验证?

我可以,至少在验证后删除任何验证错误吗?

在这种情况下,最佳做法是什么?

由于

4 个答案:

答案 0 :(得分:4)

您可以使用JSR-303 constraint groups来实现此目标。

public class User {

    public interface GroupNewUser {};

    @NotEmpty
    private String username;

    @NotEmpty(groups = {GroupNewUser.class});
    private String password;

    // ...
}

然后在控制器中,使用Spring的@Valid注释,而不是使用@Validated,它允许指定要应用的约束组。

有关详细信息,请参阅this blog postthis one also

还有superb post for Spring usage

答案 1 :(得分:3)

这是声明性验证的问题,做这种事情并不容易。

最简单的解决方案是从密码字段中删除验证注释,并在控制器中手动验证该字段。 BindingResult类上有方法可以将字段显式标记为无效。

另一种方法是创建表单类的两个子类,每个子类都有自己的密码字段,一个带有验证注释,另一个没有,并在适当的位置使用适当的一个。

答案 2 :(得分:0)

一些指示。不过我不确定它们是否有用:

Spring docs说:

  

你可以在@ Controller的@InitBinder回调中调用binder.setValidator(Validator)。这允许您根据@Controller类

配置Validator实例

javax.validation有两个*Context接口。与他们一起了解更多细节,看看是否可以在不同的环境中实现不同的验证。

答案 3 :(得分:0)

而不是使用hasErrors()函数,使用hasFieldErrors(fieldname)并仅验证表单所需的特定字段。