Question: It is possible to validate the JSON payload of a request body, without specifically writing if statements? Maybe via annotation or configuration?
I have a very easy POJO:
public class Foo {
private int important;
private String something;
//constructors, getter, seters, toString
}
And a very easy controller class:
@SpringBootApplication
@RestController
public class QuestionController {
public static void main(String[] args) {
SpringApplication.run(QuestionController.class, args);
}
@GetMapping(value = "/question")
Mono<String> question(@RequestBody Foo foo) {
System.out.println("The object foo, with value for important = " + foo.getImportant() + " and something = " + foo.getSomething());
return Mono.just("question");
}
}
If I query with a payload such as:
{
"important": 42,
"something": "value"
}
Everything is working perfectly fine, very happy.
However, if there is a typo: (note the typo on "important")
{
"importantWithTypo": 42,
"something": "value"
}
Or the required "important" is absent (note the JSON is not even complete)
{
"something": "value"
}
The request and computation are still valid! And the value of "important" is 0!
I do not want Spring to default to 0 and to thinks everything is fine.
I also do not want to change my types from primitives to boxed object.
Without me writing something like:
@GetMapping(value = "/question")
Mono<String> question(@RequestBody Foo foo) {
if (0 == foo.getImportant()) {
throw new IllegalArgumentException();
}
System.out.println("The object foo, with value for important = " + foo.getImportant() + " and something = " + foo.getSomething());
return Mono.just("question");
}
What is the most efficient way to resolve this? Some kind of annotation? Or maybe Spring boot configuration?
Thank you
Spring offers an elegant way to validate the user input. The @RequestBody annotation is used to bind the HTTP request body with a domain object in the method parameter and also this annotation internally uses the HTTP Message converter to convert the body of the HTTP request to a domain object.
Validating a RequestParam To do so, we'll use the @Min and @Max annotations: @GetMapping("/name-for-day") public String getNameOfDayByNumber(@RequestParam @Min(1) @Max(7) Integer dayOfWeek) { // ... } Any request that doesn't match these conditions will return an HTTP status 400 with a default error message.
Add @NotNull annotation on a field (you may need to change type to Integer), and add @Valid annotation on the method parameter of the controller.
Mono<String> question(@Valid @RequestBody Foo foo) {
...
}
public class Foo {
@NotNull
private Integer important;
private String something;
//constructors, getter, seters, toString
}
You can find more information here: https://lmonkiewicz.medium.com/the-power-of-spring-rest-api-validation-77be83edef
The already provided answer covers the answer.
However I would like to elaborate on one thing that you asked.
How to fail on this "importantWithTypo": 42,
2 aspects to it.
importantWithTypo
. This can be achieved by jackson's fail_on_unknown_properties property. (May be default is fail_on_unknown_properties = enabled, I havent checked so not sure).Don't do this 2nd thing. That will make your 2 services tightly coupled. By doing this fail_on_unknown_properties = enabled, you are forfeiting the potential opportunity to enhance the consumer/caller service in a nonbreaking fashion. You will have to coordinate both the apps releases.
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