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

问题描述 投票:0回答:1

我试图在请求处理之前验证枚举,

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 Status status;
}

Status.java

public enum Status {

    ACTIVE,
    IN_ACTIVE
}

在验证方面工作正常,现在消息为 value not valid emumclass package name。在这种情况下,是否有任何在错误消息中显示枚举的所有成员 ACTIVE,IN_ACTIVE

java spring-restcontroller hibernate-validator javax-validation jakarta-validation
1个回答
0
投票

由于您使用的是 Hibernate 验证器,您可以将验证器中的上下文转换为

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 {};

}
© www.soinside.com 2019 - 2024. All rights reserved.