Pio*_*ski 11 java-ee bean-validation java-ee-6
我有一个简单的豆enum田
public class TestBean{
@Pattern(regexp = "A|B") //does not work
private TestEnum testField;
//getters + setters
}
enum TestEnum{
A, B, C, D
}
Run Code Online (Sandbox Code Playgroud)
我想testField使用Bean Validation进行验证.具体来说,我想确保只允许A和B值(对于特定的calidation gropus).似乎enum没有处理JSR 303(我试图使用@Pattern验证器)或者我正在以错误的方式做某事.
我得到例外:
javax.validation.UnexpectedTypeException: No validator could be found for type: packagename.TestEnum
Run Code Online (Sandbox Code Playgroud)
有没有办法验证枚举字段而无需编写自定义验证器?
由于某些原因不支持枚举,因此可以通过简单的基于String的Validator简单地处理此限制.
验证器:
/**
* 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());
}
}
Run Code Online (Sandbox Code Playgroud)
接口:
@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
{};
}
Run Code Online (Sandbox Code Playgroud)
Validator使用apache commons库.高级强制类型方法将进一步增强此验证器的灵活性.
替代方法可以使用单个String属性而不是数组,并使用分隔符进行拆分.这也可以很好地为错误消息打印值,因为没有打印数组,但处理空值可能是一个问题String.valueOf(...)
如果要将约束放在testField上,则需要自定义验证器.没有默认值处理枚举.
作为一种解决方法,您可以添加一个getter方法,该方法返回枚举的字符串值
public class TestBean{
private TestEnum testField;
//getters + setters
@Pattern(regexp = "A|B") //does not work
private String getTestFieldName() {
return testField.name();
}
}
Run Code Online (Sandbox Code Playgroud)
自定义验证器可能是更清洁的解决方案.
我想分享我的工作解决方案:
@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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17328 次 |
| 最近记录: |