如何访问注释属性中描述的字段
是否可以访问字段值,其中字段名称在注释中描述,该注释注释了类中的另一个字段。
例如:
@Entity public class User { @NotBlank private String password; @Match(field = "password") private String passwordConfirmation; }
注解:
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = FieldMatchValidator.class) @Documented public @interface Match { String message() default "{}"; Class[] groups() default {}; Class[] payload() default {}; String field(); }
现在,是否可以从ConstraintValidator实现类中的类User访问字段密码?
编辑:
我写了这样的话:
public class MatchValidator implements ConstraintValidator { private String mainField; private String secondField; private Class clazz; @Override public void initialize(final Match match) { clazz = User.class; final Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { if (field.isAnnotationPresent(Match.class)) { mainField = field.getName(); } } secondField = match.field(); } @Override public boolean isValid(final Object value, final ConstraintValidatorContext constraintValidatorContext) { try { Object o; //Now how to get the User entity instance? final Object firstObj = BeanUtils.getProperty(o, mainField); final Object secondObj = BeanUtils.getProperty(o, secondField); return firstObj == null && secondObj == null || firstObj != null && firstObj.equals(secondObj); } catch (final Exception ignore) { ignore.printStackTrace(); } return true; } }
现在的问题是如何获取User对象实例并比较字段值?
您需要编写一个类级别约束,在该约束中,您可以将完整的User实例传递给isValid调用,或者您可以使用类似@ScriptAssert的内容 。
目前,作为“正常”字段validation的一部分,无法访问根bean实例。 有一个BVAL问题 – BVAL-237 – 讨论了添加此function,但到目前为止它尚未成为Bean Validation规范的一部分。
注意,有很好的理由说明root bean无法访问atm。 对于validateValue情况,依赖于可访问的根bean的约束将失败。
@Hardy提示小费。 最后写了一些匹配(或多或少)预期结果的代码。
我会把它贴在这里,也许会帮助别人解决他的问题。
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Match { String field(); String message() default ""; }
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = MatchValidator.class) @Documented public @interface EnableMatchConstraint { String message() default "Fields must match!"; Class>[] groups() default {}; Class extends Payload>[] payload() default {}; }
public class MatchValidator implements ConstraintValidator { @Override public void initialize(final EnableMatchConstraint constraint) {} @Override public boolean isValid(final Object o, final ConstraintValidatorContext context) { boolean result = true; try { String mainField, secondField, message; Object firstObj, secondObj; final Class> clazz = o.getClass(); final Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { if (field.isAnnotationPresent(Match.class)) { mainField = field.getName(); secondField = field.getAnnotation(Match.class).field(); message = field.getAnnotation(Match.class).message(); if (message == null || "".equals(message)) message = "Fields " + mainField + " and " + secondField + " must match!"; firstObj = BeanUtils.getProperty(o, mainField); secondObj = BeanUtils.getProperty(o, secondField); result = firstObj == null && secondObj == null || firstObj != null && firstObj.equals(secondObj); if (!result) { context.disableDefaultConstraintViolation(); context.buildConstraintViolationWithTemplate(message).addPropertyNode(mainField).addConstraintViolation(); break; } } } } catch (final Exception e) { // ignore //e.printStackTrace(); } return result; } }
以及如何使用它? 像这样:
@Entity @EnableMatchConstraint public class User { @NotBlank private String password; @Match(field = "password") private String passwordConfirmation; }
- 在Spring MVC中使用无效数据提交表单时发送的语法错误请求(使用hibernate Validator)
- Hibernate Validator – @Length – 如何为min和max指定单独的消息?
- 在@Constraint中清空validatedBy
- hibernate唯一密钥validation
- hibernatevalidation器的注释,用于将来至少24小时的日期
- Spring MVC + Hibernate:数据validation策略
- Hibernate – 激活Bean Validation集成时出错
- 如何使用Spring MVC JSR-303 Validator将不同的模型类validation为一个表单
- Beanvalidation组序列不起作用