springboot~ConstraintValidatorContext验证两个字段内容相同

敢于对过去告一个段落,才有信心掀开新的篇章! 2024-10-14 15:39:02 阅读 99

场景

我在开发修改密码功能,通过原密码和新密码及确认新密码,希望通过ConstraintValidator这个方式来校验新密码和确认新密码,规则是这两个密码需要是相同的。

参考文档

  • https://github.com/micronaut-projects/micronaut-core/issues/3243
  • https://stackoverflow.com/questions/37750656/how-to-access-a-field-which-is-described-in-annotation-property
  • https://discourse.hibernate.org/t/how-can-i-retrieve-current-validation-contexts-groups-in-a-validator/414/4

实现

定义Matches注解

<code>@Constraint(validatedBy = SameContentMatchesValidator.class)

@Target({ ElementType.FIELD })

@Retention(RetentionPolicy.RUNTIME)

public @interface SameContentMatches {

String message() default "内容不一致";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};

String field(); // 新增属性,指定要比较的字段

}

定义DTO对象

@Data

public class UserModifyPasswordDTO implements UserDTO {

@NotNull

private String userName;

@NotNull

private String password;

private String newPassword;

@SameContentMatches(field = "newPassword")

private String confirmPassword;

}

定义MatchesValidator对象,实现验证的代码逻辑

public class SameContentMatchesValidator implements ConstraintValidator<SameContentMatches, String> {

private String field;

@Override

public void initialize(SameContentMatches constraintAnnotation) {

this.field = constraintAnnotation.field();

}

@Override

public boolean isValid(String object, final ConstraintValidatorContext context) {

return true;

}

}

遇到的问题

  • 在MatchesValidator类中,无法获取到当前对象,除非把SameContentMatches注解作用到当前类上面,而非字段上面。
  • 这个问题应该主是无法解决的,因为你拦截的是字段,在这个ConstraintValidatorContext处理的都是和当前字段有关的信息

应用到类上,代码调整,问题解决

@Constraint(validatedBy = SameContentMatchesValidator.class)

@Target({ ElementType.TYPE })

@Retention(RetentionPolicy.RUNTIME)

public @interface SameContentMatches {

String message() default "内容不一致";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};

/**

* 源字段名

* @return

*/

String sourceField();

/**

* 目标字段名

* @return

*/

String destinationField();

}

public class SameContentMatchesValidator implements ConstraintValidator<SameContentMatches, Object> {

private String sourceField;

private String destinationField;

@Override

public void initialize(SameContentMatches constraintAnnotation) {

this.sourceField = constraintAnnotation.sourceField();

this.destinationField = constraintAnnotation.destinationField();

}

@Override

public boolean isValid(Object o, final ConstraintValidatorContext context) {

final Object sourceFieldVal = BeanUtil.getProperty(o, this.sourceField);

final Object destinationFieldVal = BeanUtil.getProperty(o, this.destinationField);

return sourceFieldVal.equals(destinationFieldVal);

}

}

@Data

@SameContentMatches(sourceField = "confirmPassword", destinationField = "newPassword")

public class UserModifyPasswordDTO implements UserDTO {

@NotNull

private String userName;

@NotNull

private String password;

private String newPassword;

private String confirmPassword;

}

上面的代码SameContentMatches注解出现了弱编码,这块需要再进行优化。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。