JSR-303 Bean Checking enum fields

I have a simple bean with enum field

 public class TestBean{ @Pattern(regexp = "A|B") //does not work private TestEnum testField; //getters + setters } enum TestEnum{ A, B, C, D } 

I would like to test testField using bean Validation. In particular, I would like to make sure that only values ​​A and B are valid (for a specific calibration gropus). It seems that the enums are not handled by JSR 303 (I tried using the @Pattern validator), or I'm doing something wrong.

I get an exception:

 javax.validation.UnexpectedTypeException: No validator could be found for type: packagename.TestEnum 

Is there a way to check enum fields without writing a custom validator?

+6
source share
2 answers

If you want to set a limit on testField, you will need a special validator. None of the default options handle enumerations.

As a workaround, you can add a getter method that returns the string value of the enumeration

 public class TestBean{ private TestEnum testField; //getters + setters @Pattern(regexp = "A|B") //does not work private String getTestFieldName() { return testField.name(); } } 

A custom validator is probably a cleaner solution.

+3
source

Since for some reason enumerations are not supported, this restriction can simply be handled by a simple String based Validator.

Validator:

 /** * Validates a given object 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()); } } 

Interface:

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

The validator uses the apache commons library. The advanced push method method will further increase the flexibility of this validator.

An alternative can use only one String attribute instead of an array and split by separator. It also prints the values ​​well for the error message, since arrays are not printed, but handling null values ​​can be a problem when using String.valueOf(...)

+3
source

Source: https://habr.com/ru/post/914873/


All Articles