Java Spring JSR 303验证在编辑/添加时访问其他字段值
我有一个需求,我想使用一个Bean进行更新/添加。现在我有一个验证,因为在名称中应该是唯一的 现在,在添加过程中,验证部分正常工作,因为它通过查询DB来检查唯一值 现在,当我想更新同一条记录时,它试图检查数据库中的唯一约束,但由于该记录已经存在,所以失败了 角色BeanJava Spring JSR 303验证在编辑/添加时访问其他字段值,java,validation,spring-mvc,Java,Validation,Spring Mvc,我有一个需求,我想使用一个Bean进行更新/添加。现在我有一个验证,因为在名称中应该是唯一的 现在,在添加过程中,验证部分正常工作,因为它通过查询DB来检查唯一值 现在,当我想更新同一条记录时,它试图检查数据库中的唯一约束,但由于该记录已经存在,所以失败了 角色Bean public class Role { @NotEmpty @Pattern(regexp = "[a-zA-Z ]*") @UniqueValue(query = AppConstants.UNIQUE
public class Role {
@NotEmpty
@Pattern(regexp = "[a-zA-Z ]*")
@UniqueValue(query = AppConstants.UNIQUE_VALIDATION_DB_QUERY)
private String roleName;
private String roleDesc;
private boolean active;
private String maskRoleName;
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleDesc() {
return roleDesc;
}
public void setRoleDesc(String roleDesc) {
this.roleDesc = roleDesc;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
}
我的自定义批注验证程序
public class UniqueValueValidator implements ConstraintValidator<UniqueValue, String> {
@Autowired
private ValidationDAO validationDAO;
private String query;
public void initialize(UniqueValue uniqueValue) {
this.query = uniqueValue.query();
}
public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
if (!StringUtils.isEmpty(value) && !StringUtils.isEmpty(query)) {
return validationDAO.isValidUniqueField(query, value);
}
return true;
}
}
公共类UniqueValueValidator实现ConstraintValidator{
@自动连线
私有ValidationDAO-ValidationDAO;
私有字符串查询;
公共无效初始化(UniqueValue UniqueValue){
this.query=uniqueValue.query();
}
公共布尔值有效(字符串值,ConstraintValidatorContext ConstraintValidatorContext){
如果(!StringUtils.isEmpty(值)和&!StringUtils.isEmpty(查询)){
返回validationDAO.isValidUniqueField(查询,值);
}
返回true;
}
}
现在,当我从屏幕上只更新RoleDesc字段时,角色名称被验证,并抛出验证错误,因为数据库中存在相同的角色名称。有没有一种方法可以让我从屏幕向我的自定义验证器发送另一个变量,说明下面是更新屏幕,所以只有当字段从以前的值更改时才验证它?您可能要查找的是。您可以将注释修改为:
@UniqueValue(query = AppConstants.UNIQUE_VALIDATION_DB_QUERY, groups = {CreationGroup.class})
您还需要创建一个CreationGroup
接口
然后,您需要更新调用bean验证的拦截器,以使用上下文信息(可能由另一个封装验证发生的方法的注释提供),如下所示:
if (myMethodIsCreatingANewRecord()) {
validator.validate(address, Default.class, CreationGroup.class);
} else {
validator.validate(address, Default.class);
}
我在一个getter方法上做了一个注释,其中所有必需的字段都通过该方法作为单个映射返回,在validationIMPL中,我检索了所有必需的信息并进行了相应的处理
private String roleName;
@UniqueValue(query = AppConstants.UNIQUE_VALIDATION_DB_QUERY)
public Map<String,String> getUniqueValidator(){
Map<String,String> validatorMap=new HashMap<String,String>();
validatorMap.put("ACTION",type of action(update/new)):
validatorMap.put("VALUE",this.roleName):
return validatorMap;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
私有字符串roleName;
@UniqueValue(查询=AppConstants.UNIQUE\u验证\u DB\u查询)
公共映射getUniqueValidator(){
Map validatorMap=newhashmap();
validatorMap.put(“操作”,操作类型(更新/新建)):
validatorMap.put(“VALUE”,this.roleName):
返回地图;
}
公共字符串getRoleName(){
返回roleName;
}
public void setRoleName(字符串roleName){
this.roleName=roleName;
}
但是只有当值发生变化时,我如何传递validate的信息。因为我甚至需要在添加/编辑中进行验证。。。但在编辑的情况下,我应该仅在值发生更改时进行验证。有一种方法可以将其他字段值(maskRoleName)与当前字段一起传递。。。因此,我可以检查masroleName=roleName,然后不进行验证假定您有一个主键,可以在更新时用于查找实体,以检查名称是否已更改。这是您希望与角色对象一起传递的信息。然而,对于这个特殊的问题,我可能会向数据库列添加一个唯一的约束,只要它被违反就会导致失败。谢谢你的回复。我不想在dao层之前抛出异常。相反,我想在验证层处理这个问题。是否不可能处理此类场景?如果我们可以访问我的唯一验证器中的其他变量,我认为我们可以传递有关如何验证它的信息。但我不知道是否有可能这样做??正如我在回答中提到的,您应该从调用验证器的位置获得足够的信息,以获取实体的旧版本,并使用该信息确定字段是否更改。例如,如果您的服务正在调用类似于editRole(roleId,roleBean)
的方法,那么当您截取该方法时,只需获取roleId参数并使用它加载现有实体以用于比较。