Bee
Bee

Reputation: 529

how to validate path variable in spring data rest?

My question is very simple. I am using Spring Data REST, which means I get all the endpoints by default and I am trying to validate the path. So let's say I have

/user/{string} [GET operation]

Let's say this can only be letters and I want to validate this to ensure it is not null or a number how can I achieve this?

I know one way to do this would be to override the controller, which would give me access to the parameter as it comes in and I can validate it. But this seems like too much for such a simple thing.

Upvotes: 1

Views: 2446

Answers (1)

Dale K James
Dale K James

Reputation: 204

To validate path variables you can use custom validators. You can define a custom validator @NotNumber to make sure that the path variable is not a number. The explicit check for null is not required since a null path variable will return 404.

Controller- TestController.class

    @RestController
    @RequestMapping("/")
    @Validated
    public class TestController {
    
        @PostMapping("/test/{testVariable}")
        public void signUp(@PathVariable @NotNumber String testVariable) {
            System.out.println(testVariable);
        }
    
        @ExceptionHandler(ConstraintViolationException.class)
        @ResponseStatus(HttpStatus.BAD_REQUEST)
        ResponseEntity<String> handleConstraintViolationException(ConstraintViolationException e) {
            return new ResponseEntity<>("Validation Error: " + e.getMessage(), HttpStatus.BAD_REQUEST);
        }
    }

Make sure to add @Validated on top of the controller class. This annotation, by default, returns 505 status code. To return 404, we can add the exception handler as seen above.

@NotNumber interface

    @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
    @Retention(RetentionPolicy.RUNTIME)
    @Constraint(validatedBy = NotNumberImpl.class)
    public @interface NotNumber {
        String message() default "The value of path variable must be String";
    
        Class<?>[] groups() default {};
    
        Class<? extends Payload>[] payload() default {};
    }

NotNumberImpl.class - Validator Implementation

    public class NotNumberImpl implements ConstraintValidator<NotNumber, String> {
        @Override
        public void initialize(NotNumber constraintAnnotation) {
        }
    
        @Override
        public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
            String regex = "^[0-9]";
            return s.matches(regex);
        }
    }

The regex pattern can be adjusted according to your requirement.

Upvotes: 2

Related Questions