我有一个名为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
}
...
}
但是密码为空会出错。
有没有办法只在对象的某些字段中执行验证?
我可以,至少在验证后删除任何验证错误吗?
在这种情况下,最佳做法是什么?
由于
答案 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 post和this one also。
答案 1 :(得分:3)
这是声明性验证的问题,做这种事情并不容易。
最简单的解决方案是从密码字段中删除验证注释,并在控制器中手动验证该字段。 BindingResult
类上有方法可以将字段显式标记为无效。
另一种方法是创建表单类的两个子类,每个子类都有自己的密码字段,一个带有验证注释,另一个没有,并在适当的位置使用适当的一个。
答案 2 :(得分:0)
一些指示。不过我不确定它们是否有用:
你可以在@ Controller的@InitBinder回调中调用binder.setValidator(Validator)。这允许您根据@Controller类
配置Validator实例
javax.validation
有两个*Context
接口。与他们一起了解更多细节,看看是否可以在不同的环境中实现不同的验证。
答案 3 :(得分:0)
而不是使用hasErrors()函数,使用hasFieldErrors(fieldname)并仅验证表单所需的特定字段。