Jakarta ee JSR-303枚举字段的Bean验证
我有一个带有Jakarta ee JSR-303枚举字段的Bean验证,jakarta-ee,java-ee-6,bean-validation,Jakarta Ee,Java Ee 6,Bean Validation,我有一个带有enum字段的简单bean public class TestBean{ @Pattern(regexp = "A|B") //does not work private TestEnum testField; //getters + setters } enum TestEnum{ A, B, C, D } 我想使用Bean验证来验证testField。具体来说,我想确保只允许A和B值(对于特定的校准)。看来枚举没有被JSR303处理(我试图使用@Patt
enum
字段的简单bean
public class TestBean{
@Pattern(regexp = "A|B") //does not work
private TestEnum testField;
//getters + setters
}
enum TestEnum{
A, B, C, D
}
我想使用Bean验证来验证testField
。具体来说,我想确保只允许A和B值(对于特定的校准)。看来枚举没有被JSR303处理(我试图使用@Pattern validator),或者我做了一些错误的事情
我得到一个例外:
javax.validation.UnexpectedTypeException: No validator could be found for type: packagename.TestEnum
有没有办法不用编写自定义验证器就验证枚举字段?如果您想在testField上设置约束,您需要一个自定义验证器。默认值中没有一个处理枚举 作为一种解决方法,您可以添加一个getter方法,该方法返回枚举的字符串值
public class TestBean{
private TestEnum testField;
//getters + setters
@Pattern(regexp = "A|B") //does not work
private String getTestFieldName() {
return testField.name();
}
}
不过,自定义验证器可能是更干净的解决方案。由于某些原因,不支持枚举,因此可以通过简单的基于字符串的验证器简单地处理此限制 验证程序:
/**
* Validates a given object's String representation to match one of the provided
* values.
*/
public class ValueValidator implements ConstraintValidator<Value, Object>
{
/**
* String array of possible enum values
*/
private String[] values;
@Override
public void initialize(final Value constraintAnnotation)
{
this.values = constraintAnnotation.values();
}
@Override
public boolean isValid(final Object value, final ConstraintValidatorContext context)
{
return ArrayUtils.contains(this.values, value == null ? null : value.toString());
}
}
@Target(value =
{
ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER
})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy =
{
ValueValidator.class
})
@Documented
public @interface Value
{
public String message() default "{package.Value.message}";
Class<?>[] groups() default
{};
Class<? extends Payload>[] payload() default
{};
public String[] values() default
{};
}
/**
*验证给定对象的字符串表示形式以匹配提供的
*价值观。
*/
公共类ValueValidator实现ConstraintValidator
{
/**
*可能枚举值的字符串数组
*/
私有字符串[]值;
@凌驾
公共无效初始化(最终值CONSTRAINTANOTATION)
{
this.values=constraintanotation.values();
}
@凌驾
公共布尔值有效(最终对象值、最终约束验证或上下文上下文)
{
返回ArrayUtils.contains(this.values,value==null?null:value.toString());
}
}
界面:
/**
* Validates a given object's String representation to match one of the provided
* values.
*/
public class ValueValidator implements ConstraintValidator<Value, Object>
{
/**
* String array of possible enum values
*/
private String[] values;
@Override
public void initialize(final Value constraintAnnotation)
{
this.values = constraintAnnotation.values();
}
@Override
public boolean isValid(final Object value, final ConstraintValidatorContext context)
{
return ArrayUtils.contains(this.values, value == null ? null : value.toString());
}
}
@Target(value =
{
ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER
})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy =
{
ValueValidator.class
})
@Documented
public @interface Value
{
public String message() default "{package.Value.message}";
Class<?>[] groups() default
{};
Class<? extends Payload>[] payload() default
{};
public String[] values() default
{};
}
@Target(值=
{
ElementType.METHOD、ElementType.FIELD、ElementType.ANNOTATION\u TYPE、ElementType.CONSTRUCTOR、ElementType.PARAMETER
})
@保留(RetentionPolicy.RUNTIME)
@约束(validatedBy)=
{
ValueValidator.class
})
@记录
公共@接口值
{
公共字符串message()默认值“{package.Value.message}”;
类[]组()默认值
{};
Class我想分享我的工作解决方案:
@Documented
@Constraint(validatedBy = { EnumValueValidator.class })
@Retention(RetentionPolicy.RUNTIME)
@Target({
ElementType.ANNOTATION_TYPE,
ElementType.CONSTRUCTOR,
ElementType.FIELD,
ElementType.METHOD,
ElementType.PARAMETER
})
public @interface EnumValue
{
public abstract String message() default "{validation.enum.message}";
public abstract Class<?>[] groups() default {};
public abstract Class<? extends Payload>[] payload() default {};
public abstract Class<? extends java.lang.Enum<?>> enumClass();
}
public class EnumValueValidator implements ConstraintValidator<EnumValue, Object>
{
private Object[] enumValues;
@Override
public void initialize(final EnumValue annotation)
{
enumValues = annotation.enumClass().getEnumConstants();
}
@Override
public boolean isValid(final Object value, final ConstraintValidatorContext context)
{
if (null != value) {
String contextValue = value.toString();
for (Object enumValue : enumValues) {
if (enumValue.toString().equals(contextValue)) {
return true;
}
}
}
return false;
}
@已记录
@约束(validatedBy={EnumValueValidator.class})
@保留(RetentionPolicy.RUNTIME)
@目标({
ElementType.ANNOTATION_类型,
ElementType.CONSTRUCTOR,
ElementType.FIELD,
ElementType.METHOD,
ElementType.PARAMETER
})
public@interface枚举值
{
公共抽象字符串message()默认值“{validation.enum.message}”;
公共抽象类[]组()默认值{};
公共抽象类>枚举类();
}
公共类EnumValueValidator实现ConstraintValidator
{
私有对象[]枚举值;
@凌驾
公共void初始化(最终枚举值注释)
{
enumValues=annotation.enumClass().getEnumConstants();
}
@凌驾
公共布尔值有效(最终对象值、最终约束验证或上下文上下文)
{
if(null!=值){
字符串contextValue=value.toString();
用于(对象枚举值:枚举值){
if(enumValue.toString().equals(contextValue)){
返回true;
}
}
}
返回false;
}