5

I have a simple Controller method :

@GetMapping("/search")
    public List<Result> search(@RequestParam @Valid @NotNull @Size(min = 4) String query) {
        return searchService.search(query);
    }

When I omit the "query" parameter, I get a 400 Bad Request, as expected.

Testing the method with these query parameters doesn't work.

All but the last test should return a "400 Bad Request".

"/search"             --> actual 400 Bad Request, test passes
"/search?query="      --> actual 200 Ok, expected 400 because @Size(min=4)
"/search?query=a"     --> actual 200 Ok, expected 400 because @Size(min=4)
"/search?query=ab"    --> actual 200 Ok, expected 400 because @Size(min=4)
"/search?query=abc"   --> actual 200 Ok, expected 400 because @Size(min=4)
"/search?query=abcd"  --> actual 200 Ok, test passes

Why is the @Size(min=4) annotation being ignored?

0

2 Answers 2

5

Validating RequestParameters does not work like that out of the box.

You could wrap the parameters in a class like

class SearchRequest {
    @Size(min=4)
    @NotNull
    private String query;
    ...
}

Then change your controller code to

@GetMapping("/search")
public List<Result> search(@ModelAttribute @Valid SearchRequest searchRequest) {
    return searchService.search(searchRequest.getQuery());
}

Now this is one way to do it, what you want is probably achievable using the @Validated annotation on the class, but I don't know anything about that but it seems to be covered here: https://sdqali.in/blog/2015/12/04/validating-requestparams-and-pathvariables-in-spring-mvc/

Sign up to request clarification or add additional context in comments.

Comments

3

You can use RequestParameters validation out of the box)

You need to add MethodValidationPostProcessor to your configuration

@org.springframework.context.annotation.Configuration
public class Configuration {

    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        return new MethodValidationPostProcessor();
    }

}

And @Validated Annotation to your controller

@RestController
@Validated
public class MyController {

    @GetMapping("/search")
    public String search(@RequestParam @NotNull @Size(min = 4) String query) {
        return "success";
    }

}

Remember also, that you may want to handle exception, which is thrown if method parameters not valid, you may do it like this

@ControllerAdvice
@Component
public class ExceptionHandler {
    @ExceptionHandler
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public List handle(MethodArgumentNotValidException exception) {
        //do your stuff here
        return exception.getBindingResult().getFieldErrors()
                .stream()
                .map(FieldError::getDefaultMessage)
                .collect(Collectors.toList()));
    }


    @ExceptionHandler
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public List handle(ConstraintViolationException exception) {
       //do your staff here
    }

}

1 Comment

using spring boot v2. this solution didn't work for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.