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?
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/
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
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With