Short answer to your question: No, you can't just add an extra field, nor can you use inheritance too add the extra field. See this question which explains why Java doesn't allow inheritance with annotations.
What you'll have to do is create your own particular version of the @Size
annotation. But you should be able to apply the @Size
annotation to your custom annotation so that @Size
is checked automatically when you run your validations.
Your annotation would probably look something like this:
@Constraint(validatedBy = { })
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@ReportAsSingleViolation
//The only downside of this approach
//is that you have to hardcode your min and max values
@Size(min=5, max=10)
public @interface CodedSize {
String message() default "{Default Validation Message}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
int code() default 0;
}
If you wanted to specify the size as well in the annotation, you could do that, and write a custom validator that validates your annotation.
@Constraint(validatedBy = { CodedSizeValidator.class })
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface CodedSize {
String message() default "{Default Validation Message}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
int minSize() default 5;
int maxSize() default 10;
int code() default 0;
}
Then your custom validator looks something like this:
public class CodedSizeValidator implements ConstraintValidator<CodedSize, String> {
private int minSize;
private int maxSize;
private int code;
@Override
public void initialize(CodedSize constraintAnnotation){
this.minSize = constraintAnnotation.minSize();
this.maxSize = constraintAnnotation.maxSize();
this.code = constraintAnnotation.code();
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
boolean isValid = false;
if(value == null || value.isEmpty()) {
//if a null or empty value is valid, then set it here.
isValid = true;
} else {
//Logic here to determine if your value is valid by size constraints.
}
return isValid;
}
}
I used String
because that seemed the most applicable, but you could easily use Number
, or even a generic type to allow you to use this annotation on more than one field. The advantage of doing it this way is that if you want to add a null check in with this validation, you can do so.
The ConstraintValidatorContext
can be used to build out your error message if multiple validations fail. You can make this as detailed as you want, but be aware that this code can spaghetti-fy very quickly.