开发者

springboot中使用ConstraintValidatorContext验证两个字段内容相同

开发者 https://www.devze.com 2024-10-18 11:09 出处:网络 作者: 张占岭
目录场景参考文档实现定义Matches注解定义DTO对象定义MatchesValidator对象,实现验证的代码逻辑遇到的问题应用到类上,代码调整,问题解决场景
目录
  • 场景
  • 参考文档
  • 实现
    • 定义Matches注解
    • 定义DTO对象
    • 定义MatchesValidator对象,实现验证的代码逻辑
    • 遇到的问题
    • 应用到类上,代码调整,问题解决

场景

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

参考文档

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

实现

定义Matches注解

@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 so编程urceFieldVal.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注解出现了弱编码,这块需要再进行优化。

到此这篇关于springboot中使用ConstraintValidatorContext验证两个字段内容相同的文章就介绍到这了,更多相关springboot验证字段内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号