How to Validate JSON Request Body in Spring Boot
1. Overview
We sometimes encounter server errors caused by a user providing input that’s longer than the database column size or
even a non-existent ENUM
value. Do not trust user input is a popular cliché that,
if implemented, will save a lot of time and resources down the line.
That is why, in this article, we will be looking at the request-validator library, which is able to compare the user input against a pre-defined set of rules and return errors if any.
2. Dependency Installation
In order for us to use request-validator, we need to add it to our project’s pom.xml
:
Listing 2.1 pom.xml
|
|
The latest version of the dependency is available on Maven central.
3. Validating JSON Request Body
Given that we have a simple login endpoint that requires a valid email and password and as a good Engineer we want to ensure that the user sends both fields and the email is a valid one.
We can easily achieve this with the request-validator library. For the email
input field, we want the user to provide
a non-null field and a valid email address while for the password
field, we just want the user to provide a non-null value:
Listing 3.1 LoginController.java
|
|
From Listing 3.1 above, we used a Map<String, String>
to store the rules for each expected request field.
The key of the map is the name of the field as the API user should supply it, while the value contains the validation rules.
We then call the RequestValidator.validate()
method to check the incoming request object against the defined rules.
The method returns a List<String>
that’ll contain all the error messages if there are violations.
One big advantage of the library is that it returns a separate descriptive error message for each rule and checks ALL the rules in a single invocation.
Because RequestValidator.validate()
expects Object data type, the request object can be a Map
, a POJO or even a JSON
String.
If an API user provides an invalid request body, they’ll get a 400 Bad Request with a detailed list of all the data infractions:
Listing 3.2 Curl Request/Response
|
|
However, as expected, a valid request body will return success:
Listing 3.3 Curl Request/Response
|
|
Note that the returned List<String>
of errors can be used as part of your response in any way you and your team have chosen.
It’s not limited to the response format demonstrated in this article.
The complete source code is available at the end of this article and will help you better understand how the response format in this tutorial is formatted.
The request validator library allows us to combine one or more rules together using the pipe (|
) character as a separator.
From Listing 3.1 above, we combined the required
and email
rules together using the |
.
The only exception to this is when using the regex rule with other rules. It should be the last rule and should be separated by double pipe characters as in ||
.
This is to accommodate the potential presence of the pipe character in the regex pattern.
Listing 3.3 Regex Pattern
|
|
The complete list of rules is available here.
4. Defining Custom Rules
Let’s say we want to add a custom validation rule that’s not in the library by default,
we can easily achieve it by subclassing the RequestValidator
class and implementing the RuleValidator
interface.
Given that we need to add a rule to ensure the user-provided value starts with custom_
, first,
we will need to create a PrefixRuleValidator
class that’ll implement the RuleValidator
interface and perform the custom logic:
Listing 4.1 PrefixRuleValidator.java
|
|
The next component we need is a class that will extend RequestValidator
. We will be calling this CustomRequestValidator
,
instead of the library’s RequestValidator
, to do our checks:
Listing 4.2 CustomRequestValidator.java
|
|
The structure of CustomRequestValidator
is very simple, we statically added the PrefixRuleValidator
class to the parent’s ruleValidatorMap
.
We then proceed to create a copy of the parent’s validate()
method, this will effectively make our rules to be available alongside other default rules.
Finally, let’s use our custom rule in a controller:
Listing 4.3 CustomPrefixController.java
|
|
Posting a valid request will return 200 OK:
Listing 4.4 Curl Request/Response
|
|
On the other hand, posting an invalid request will return the error message as coded in Listing 4.1 PrefixRuleValidator.java
:
Listing 4.5 Curl Request/Response
|
|
5. Conclusion
In this article, we’ve seen how we can easily validate the JSON request body and ensure the API consumers are sending the data we expect alongside practical examples. The complete source code is available on GitHub.
Happy coding