英文:
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<? 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
}
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<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());
}
}
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<? extends Enum<?>> enumClass();
String message() default "value not valid {enumClass}. Available options: {enumConstants}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论