Use Case:
Annotate with the Validator.
The default behavior of the @Valid annotation in a spring controller is to validate all the annotation. This works well when we need to validate all the input received from the form. This is true for most of the cases. But there can arise a scenario when we need to implement a multistep form, where the data is captured in multiple steps. For example lets take an scenario where we want to capture user details where the user detail can be split into multiple forms namely:
- User Personal Details
- User Address
- Additional Details
Now if we define a single model for capturing all the details we would have to build our model catering to these three details separately. Instead we can have a single model containing all the details, and Group the validation for each type. This will enable us to capture the details into the same model in multiple steps and on each submission only the relevant fields can be validated.
User Details | Address | Contact Detail |
First name | Hose Number | Mobile Number |
Middle Name | Street | email id |
Last Name | Locality | Phone Number |
Date of Birth | City | |
Zip Code |
Spring Version Required:
Springframework -- 4.1.1.RELEASE
Hibernate Validator -- 5.1.2.Final
Annotate with the Validator.
public class CustomerDetailsModel {
public interface PersonalDetails{}
public interface AddressDetails{}
public interface ContacDetails{}
long customerId;
@NotNull(groups={PersonalDetails.class})
@NotBlank(groups={PersonalDetails.class})
@Size(max=35,groups={PersonalDetails.class})
String firstName;
@NotNull(groups={PersonalDetails.class})
@NotBlank(groups={PersonalDetails.class})
@Size(max=35,groups={PersonalDetails.class})
@Size(max=35,groups={PersonalDetails.class})
String middleName;
String lastName;
@Past(groups={PersonalDetails.class})
Date dateOfBirth;
@Size(max=20,groups={ContacDetails.class})
String mobileNumber;
@NotNull(groups={ContacDetails.class})
@NotBlank(groups={ContacDetails.class})
@Email(groups={ContacDetails.class})
@Size(max=100,groups={ContacDetails.class})
String emailId;
@Size(max=20,groups=AddressDetails.class)
String houseNumber;
@Size(max=20,groups=AddressDetails.class)
String street;
int zipCode;
@Size(max=30,groups=AddressDetails.class)
String city;
//..... Gettrs and setters goes here
}
One can notice that there are three validation groups defined in the model and corresponding to each an interface is defined in the class.
Note: More than one validation group can be grouped together by just including the same, e.g ContactDetails and AddressDetails can be grouped in the Controller using the below mentioned syntax:
Using @Validated along with the Group validator can provide you with a partial validation of the model instead of the full model.
Reference:
- PersonalDetails
- AddressDetails
- ContactDetails
The interface can be defined either within the class or it can be defined independently. The purpose of the Interface is to differentiate the various groups.
Using the Group Validation in a Controller:
Using the controller group validation with the controller is very simple.
Using the controller group validation with the controller is very simple.
//Capture and Validate personal Detail
@RequestMapping(value = "/customer/updatepersonalDetails", method = RequestMethod.POST)
@ResponseBody
public CustomerDetailsModel updatePersonalDetail(
@RequestBody @Validated({CustomerDetailsModel.PersonalDetails.class}) CustomerDetailsModel customerDetails) {
}
//Capture and Validate Address Detail
@RequestMapping(value = "/customer/updateaddressDetails", method = RequestMethod.POST)
@ResponseBody
public CustomerDetailsModel updateAddressDetail(
@RequestBody @Validated({CustomerDetailsModel.AddressDetails.class}) CustomerDetailsModel customerDetails) {
}
//Capture and Validate Contact Detail Only
@RequestMapping(value = "/customer/updatecontactDetails", method = RequestMethod.POST)
@ResponseBody
public CustomerDetailsModel updateAddressDetail(
@RequestBody @Validated({CustomerDetailsModel.ContactDetails.class}) CustomerDetailsModel customerDetails) {
}
Note: More than one validation group can be grouped together by just including the same, e.g ContactDetails and AddressDetails can be grouped in the Controller using the below mentioned syntax:
@Validated({CustomerDetailsModel.AddressDetails.class,CustomerDetailsModel.ContactDetails.class})Conclusion:
Using @Validated along with the Group validator can provide you with a partial validation of the model instead of the full model.
Reference: