Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validate UUID Restful service

I have a RESTful service which receives POST request with UUID values and writes them in DB. So the problem is to validate if UUID is valid or not. For this purpose I implemented custom annotation:

@Constraint(validatedBy = {})
@Target({ElementType.FIELD})
@Retention(RUNTIME)
@Pattern(regexp = "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[34][0-9a-fA-F]{3}-[89ab][0-9a-fA-F]{3}-[0-9a-fA-F]{12}")
public @interface validUuid {

    String message() default "{invalid.uuid}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

But for some reason it doesn't work, even if I pass valid UUID I constantly get an exception:

javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 'javax.validation.constraints.Pattern' validating type 'java.util.UUID'

Are there any options to validate UUID properly?

like image 477
Abraksis Avatar asked Dec 20 '18 12:12

Abraksis


1 Answers

You cannot apply the @Pattern annotation to something (java.util.UUID) that is not a CharSequence. From the @Pattern annotation documentation (emphesizes mine):

Accepts CharSequence. null elements are considered valid.

Moreover, as far as I see you try to extend the behavior of the validation annotation handler by passing it to the new annotation definition.

If you wish to perform more complex validation, simply create your annotation without another validation annotations - their combining doesn't work like this. There must be something to recognize annotations and validate them.

@Target({ElementType.FIELD})
@Retention(RUNTIME)
@Constraint(validatedBy = UuidValidator.class)
public @interface ValidUuid {

    String message() default "{invalid.uuid}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

Now, create a validator which implements ConstraintValidator<ValidUuid, UUID> and override the methods performing the validation itself.

public class UuidValidator implements ConstraintValidator<ValidUuid, UUID> {
    private final String regex = "....." // the regex

    @Override
    public void initialize(ValidUuid validUuid) { }

    @Override
    public boolean isValid(UUID uuid, ConstraintValidatorContext cxt) {
        return uuid.toString().matches(this.regex);
    }
}

And apply the annotation:

@ValidUuid
private UUID uuId;
like image 139
Nikolas Charalambidis Avatar answered Nov 13 '22 16:11

Nikolas Charalambidis