In a project or an API, testing the request fields for for null values or for custom checks is quiet common. Generally, to check for a null value or for a particular password pattern or for a URL validation, we need to perform manual checks on the form data fields or on the incoming API request body. These checks are rather repetitive in nature and can be cumbersome some times as well.
Further, they are standard coding practices and the logic generally remain the same irrespective of the type or project. Hence Spring provides built-in methods/annotations for such tasks. Validations in spring boot (or Validators) are basically checks that are used to test the authenticity of an input field. Eg:- A valid Password, Email etc..
To enable the usage of basic validators in our spring project, we need to have one main dependency i.e. spring-boot-starter-validation. This enables basic setup for spring validation along with it’s annotations. Spring validators can be used anywhere, in a controller, a class, a method, field or even in a parameter. Generally, we work with validators in case of REST API calls and as such the basic requirement is to annotate our controller class with @Validated annotation belonging to springframework.validations package. Spring provides built-in support for some basic validators which are as follows:-
- Checking for NULL values in case of a GET API:-
Here, the GET api takes “data” as a parameter and to ensure that the string data is not empty, we use @NotNull annotation. Now suppose we have a POST request taking some payload as some custom class. In such case, we can use the following approach:-
Let’s have a class called CustomRequest which takes in Request from controller. This class has following:-
Also, we have a new controller as follows: -
So now, hitting on the URL will send the request to body, even if the name field is empty. So, in order to check such empty requests we can use NotNull in the following way:-
This will check for null in the custom requests and throw an error as per the message given in brackets. Also we need to add @Valid annotation just after the @RequestBody to let know spring that this custom request class needs to be checked.
- Checking for email validations
Suppose we have a POST request having email field which needs to be checked whether the incoming value is an email or not. Generally we can extract the field and using string manipulation but this is again standard and spring has a better way to automate this standardization. Since it’s an example of POST request, we have the following:-
Similarly, on the controller
For a GET request, this can be modified in the following way:-
Similar to the above examples, Spring provides many standard validators which can be used in a similar way with http handlers. But what if the validation which we need isn’t provided in spring validations? In such cases, we can create custom validators which can be used anywhere in the project in a similar way as shown above.
Custom Validators are user defined validators which help in skinning code repetition on basic or complex checks like password validations, phone number validations etc. Creating a custom validation requires 3 basic steps:-
a. Defining an interface:- An interface is basically the abstract implementation of a class. By using interface here, we basically define our custom annotation which is of the same name as the interface( here it’s isValidPassword). The code for the same is as follows:-
The class inside validatedBy field has the logic we need to perform the check on password
b. Define the validator class:- The validator class or the class as mentioned above looks like:-
Here, initialize() is called only once and isValid() contains the logic we will use to check for a valid password. Importantly, in case of violation of this validator, the message inside message() will be thrown. In case we have some custom exception handler and want more flexibility in terms of error throwing, then we can override the isValid() method in the following way:-
c. Using the implementation:- Now our validator is like any other pre-built validator and hence It’s usage is similar to what we saw above . We just need to type @ourValidatorName (here @isValidPassword) on the class, field, parameter, etc. (usage as per the allowed fields declared above) and we are good to go!
Although, there can be many ways to use custom or pre-built validators but the above way is simple, easy and works fine in any environment.
Thanks for reading!!