枚举类型的约束验证中的动态验证消息

huangapple go评论75阅读模式
英文:

Dynamic Validation message in Constraint Validation of Enums

问题

我正在尝试在请求处理之前验证枚举。

EnumValidator.java

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EnumValidatorImpl.class)
public @interface EnumValidator {

    Class<? extends Enum<?>> enumClass();

    String message() default "value not valid {enumClass}";

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

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

}

EnumValidatorImpl.java

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.List;
import java.util.stream.Stream;

public class EnumValidatorImpl implements ConstraintValidator<EnumValidator, Enum<?>> {

    private List<String> allowableValues;

    @Override
    public void initialize(EnumValidator constraintAnnotation) {
        allowableValues = Stream.of(constraintAnnotation.enumClass()
                .getEnumConstants())
                .map(Enum::name)
                .toList();
    }

    @Override
    public boolean isValid(Enum<?> anEnum, ConstraintValidatorContext constraintValidatorContext) {
        return anEnum != null && allowableValues.contains(anEnum.name());
    }
}

Person.java

import lombok.Data;

@Data
public class Person {

    @EnumValidator(enumClass = Status.class)
    private String status;
}

Status.java

public enum Status {

    ACTIVE,
    IN_ACTIVE
}

在验证方面它运行良好,但是现在错误消息显示为value not valid emumclass包名。在这种情况下,有没有办法在错误消息中显示枚举的所有成员,例如ACTIVE,IN_ACTIVE?

英文:

I was trying to Validate the Enum before Request Processing,

EnumValidator.java

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EnumValidatorImpl.class)
public @interface EnumValidator {

    Class&lt;? extends Enum&lt;?&gt;&gt; enumClass();

    String message() default &quot;value not valid {enumClass}&quot;;

    Class&lt;?&gt;[] groups() default {};

    Class&lt;? extends Payload&gt;[] payload() default {};

}

EnumValidatorImpl.java

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.List;
import java.util.stream.Stream;

public class EnumValidatorImpl implements ConstraintValidator&lt;EnumValidator, Enum&lt;?&gt;&gt; {

    private List&lt;String&gt; allowableValues;

    @Override
    public void initialize(EnumValidator constraintAnnotation) {
        allowableValues = Stream.of(constraintAnnotation.enumClass()
                .getEnumConstants())
                .map(Enum::name)
                .toList();
    }

    @Override
    public boolean isValid(Enum&lt;?&gt; anEnum, ConstraintValidatorContext constraintValidatorContext) {
        return anEnum != null &amp;&amp; allowableValues.contains(anEnum.name());
    }
}

Person.java

import lombok.Data;

@Data
public class Person {

    @EnumValidator(enumClass = Status.class)
    private String status;
}

Status.java

public enum Status {

    ACTIVE,
    IN_ACTIVE
}

It was working fine in-terms of validation, Right now the message comes as value not valid emumclass package name. Is there any to display all the members of enum in error message in this case ACTIVE, IN_ACTIVE

答案1

得分: 0

由于您正在使用Hibernate Validator,您可以将验证器中的上下文转换为HibernateConstraintValidatorContext,这将允许您添加额外的消息参数:

public class EnumValidatorImpl implements ConstraintValidator<EnumValidator, Enum<?>> {

	private List<String> allowableValues;

	@Override
	public void initialize(EnumValidator constraintAnnotation) {
		allowableValues = Stream.of(constraintAnnotation.enumClass()
						.getEnumConstants())
				.map(Enum::name)
				.toList();
	}

	@Override
	public boolean isValid(Enum<?> anEnum, ConstraintValidatorContext constraintValidatorContext) {
		if (constraintValidatorContext instanceof HibernateConstraintValidatorContext) {
			((HibernateConstraintValidatorContext) constraintValidatorContext).addMessageParameter(
					"enumConstants", allowableValues);
		}
		return anEnum != null && allowableValues.contains(anEnum.name());
	}
}

然后在消息模板中使用这些消息参数:

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EnumValidatorImpl.class)
public @interface EnumValidator {

    Class<? extends Enum<?>> enumClass();

    String message() default "value not valid {enumClass}. Available options: {enumConstants}";

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

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

}
英文:

Since you are using the Hibernate Validator you can cast the context in the validator to HibernateConstraintValidatorContext, and that would allow you to add additional message parameters:

public class EnumValidatorImpl implements ConstraintValidator&lt;EnumValidator, Enum&lt;?&gt;&gt; {

	private List&lt;String&gt; allowableValues;

	@Override
	public void initialize(EnumValidator constraintAnnotation) {
		allowableValues = Stream.of(constraintAnnotation.enumClass()
						.getEnumConstants())
				.map(Enum::name)
				.toList();
	}

	@Override
	public boolean isValid(Enum&lt;?&gt; anEnum, ConstraintValidatorContext constraintValidatorContext) {
		if ( constraintValidatorContext instanceof HibernateConstraintValidatorContext ) {
			( (HibernateConstraintValidatorContext) constraintValidatorContext ).addMessageParameter(
					&quot;enumConstants&quot;, allowableValues );
		}
		return anEnum != null &amp;&amp; allowableValues.contains(anEnum.name());
	}
}

and then use these message parameters in the message template:

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EnumValidatorImpl.class)
public @interface EnumValidator {

    Class&lt;? extends Enum&lt;?&gt;&gt; enumClass();

    String message() default &quot;value not valid {enumClass}. Available options: {enumConstants}&quot;;

    Class&lt;?&gt;[] groups() default {};

    Class&lt;? extends Payload&gt;[] payload() default {};

}

huangapple
  • 本文由 发表于 2023年8月9日 13:40:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76864869.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定