Validation is like a quality check for data, Spring Boot provides various mechanisms for validation, including annotations, custom validators, error handling and group validation.
In Spring Boot, validation is made easier with annotations that mark fields with specific validation rules. Let’s consider an example of validating a simple registration form for a customer:
public class CustomerRequest {
@JsonProperty("customerName")
@NotBlank(message = "Please provide username")
private String customerName;
@JsonProperty("customerAge")
@NotBlank(message = "Please provide customerAge")
private int customerAge;
@JsonProperty("customerMobileNumber")
@NotBlank(message = "Please provide customerMobileNumber")
@Size(min = 10, max = 10, message = "Please provide the valid mobile number")
private String customerMobileNumber;
@JsonProperty("customerEmailAddress")
@NotBlank(message = "Please provide customerEmailAddress")
@Email(message = "please provide valid email address")
private String customerEmailAddress;
@JsonProperty("customerAddress")
@NotBlank(message = "Please provide customerAddress")
private String customerAddress;
}
When you apply the @Valid annotation to a method parameter, Spring Boot automatically triggers validation for that parameter before the method is invoked. It is placed before the object to indicate that it should be validated. This means that the incoming data for that parameter will be validated against the specified validation rules.
@PostMapping("/create")
public ResponseEntity<APIResponse> createCustomer(@RequestBody @Valid CustomerRequest request, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return ResponseEntity.ok(APIResponse.builder()
.errorCode(HttpStatus.BAD_GATEWAY.value())
.errorMessage(HttpStatus.BAD_GATEWAY.toString())
.data(bindingResult.getFieldErrors().stream()
.map(fieldError -> fieldError.getDefaultMessage())
.toList())
.build());
}
return customerService.createCustomer(request);
}
If the data fails validation, Spring Boot will automatically generate validation error messages and associate them with the appropriate fields in the input data. These validation errors are typically captured in a BindingResult object, which you can access to analyze and handle validation failures.
When dealing with complex objects that have nested properties requiring validation, you can use the @Valid annotation along with validation annotations to ensure that both the top-level object and its nested properties are properly validated.
// Customer address annotated with @Valid in CustomerRequest object
@JsonProperty("customerAddress")
@Valid
private CustomerAddress customerAddress;
public class CustomerAddress {
@JsonProperty("address")
@NotBlank(message = "Please provide the customer address")
private String address;
@JsonProperty("city")
private String city;
@JsonProperty("state")
private String state;
@JsonProperty("country")
@NotBlank(message = "Please provide the country")
private String country;
}
Full source code is available in follwong GitHub repository: SpringBoot Form Validations