When building any application, it is necessary to handle all possible behaviors when users use our application. One of the cases you will often face when working with Spring MVC applications is that the request data that the user transmits will not correct the expectation so that our application can handle. To avoid these situations, you can use Bean Validation with Spring MVC to prevent such data requests. How is it in details? Let’s find out in this tutorial!
First, I will create a new Spring Boot project with Web Starter dependency for example:
Now I will create a new controller with a simple request like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package com.huongdanjava.springmvcvalidation; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping("/hello") public String hello(@RequestParam Integer id) { return id + ""; } } |
Validating the data type of the request parameter “id” in the above example, by defaults, Spring MVC handles already:
In the above request, I pass the value to the request parameter id as “Khanh” but the data type of this parameter must be Integer so Spring MVC will respond to the error message.
But in case, we need the value of the request parameter id from users must be greater than or equal to 10 for example, Spring MVC by default does not help us with this. In that case, we can use the code to do this, for example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package com.huongdanjava.springmvcvalidation; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping("/hello") public String hello(@RequestParam Integer id) { if (id < 10) { return "Not valid id"; } return id + ""; } } |
or use Java’s Bean Validation as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package com.huongdanjava.springmvcvalidation; import javax.validation.constraints.Min; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @Validated public class HelloController { @GetMapping("/hello") public String hello(@RequestParam @Min(10) Integer id) { return id + ""; } } |
In the above code, I used the @Min annotation of the Java Bean Validation to declare the constraint for the value of the request parameter id must be greater than or equal to 10 and it is mandatory that you declare the @Validated annotation of Spring.
If the request with the value of the request parameter id is greater than 10, the result will look like this:
Similar to requests with request parameters, if your application uses path variable:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package com.huongdanjava.springmvcvalidation; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping("/{id}") public String hello(@PathVariable Integer id) { return id + ""; } } |
then you can also use Java Bean Validation with @Validated annotation of Spring as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package com.huongdanjava.springmvcvalidation; import javax.validation.constraints.Min; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @RestController @Validated public class HelloController { @GetMapping("/{id}") public String hello(@PathVariable @Min(10) Integer id) { return id + ""; } } |
Result:
For requests that request data in the body such as a POST request, we can also apply Bean Validation to the object that holds the information of the request data.
For example, I have a POST request that transmits student information:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package com.huongdanjava.springmvcvalidation; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @PostMapping("/student") public String student(@RequestBody Student student) { return student.getName(); } } |
with the student information defined using Bean Validation as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
package com.huongdanjava.springmvcvalidation; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; public class Student { @NotNull private String name; @Min(value = 18) private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } |
With the above definition, I want the student information to have name and age must be greater than or equal to 18.
To enable Bean Validation in Spring MVC with requests that data is in the body, we will use @Valid annotation of Bean Validation as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package com.huongdanjava.springmvcvalidation; import javax.validation.Valid; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @PostMapping("/student") public String student(@Valid @RequestBody Student student) { return student.getName(); } } |
The result if I request the invalid request will be as follows: