I have a custom Java Bean Validation constraint annotation and apply it to a single Jakarta Part field using:
@AllowedFileExtensions({".jpg", ".png"})
private Part file;
This is the constraint annotation class:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
@Constraint(validatedBy = {AllowedFileExtensionsValidator.class})
public @interface AllowedFileExtensions {
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String message() default
"{com.annotation.constraint.AllowedFileExtensions}";
String[] value() default {};
}
And this is the constraint validator class:
import com.annotation.constraint.AllowedFileExtensions;
import jakarta.servlet.http.Part;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import java.util.Arrays;
public class AllowedFileExtensionsValidator
implements ConstraintValidator<AllowedFileExtensions, Part> {
private String[] extensions;
@Override
public void initialize(AllowedFileExtensions constraintAnnotation) {
this.extensions = constraintAnnotation.value();
}
@Override
public boolean isValid(Part part, ConstraintValidatorContext context) {
return Arrays.stream(extensions).anyMatch(type -> part.getSubmittedFileName().endsWith(type));
}
}
I know this constraint annotation is designed to only work on a single Part field, but is it possible to refactor it to support reuse of the same constraint annotation on a field that is either a single Part
or a field that is an array Part[]
or a list List<Part>
?
Example:
@AllowedFileExtensions({".jpg", ".png"})
private Part[] files;
// or
@AllowedFileExtensions({".jpg", ".png"})
private List<Part> files;
What would be best practice in this case from the perspective of Bean Validation, should a separate constraint annotation be created to specifically handle the array or list of Parts? Or should I aim to reuse the same constraint annotation across the different types somehow?