GenAI has transformed nearly every industry. Our research dives into developer use cases and sentiments on its organizational impact.

Automation and compliance made easy. Learn how to streamline your DevOps processes, enhance compliance and risk mitigation, and get results

Agentic AI. It's everywhere. But what does that mean for developers? Learn to leverage agentic AI to improve efficiency and innovation.

Internal Developer Portals are reshaping the developer experience. What's the best way to get started? Do you build or buy? Tune in to see.

Implementing Validation for RESTful Services With Spring Boot

Validation is an important part of an application, be it a website or a service. So, we look at how to implement validation for a Spring Boot-based RESTful service.

By  · Tutorial
Comment (1)
Save
127.7K Views

This guide will help you implement effective validations for a REST API/Service with Spring Boot.

You Will Learn

  • What is validation?
  • Why do you need validation?
  • What is Hibernate Validator?
  • What is Bean Validation API?
  • What are the default validation capabilities provided by Spring Boot?
  • How to implement validation with Spring Boot?
  • How to implement validation with Bean Validation API?

Project Code Structure

The following files contain the important components of the project we will create. 

A few details:

  • SpringBoot2RestServiceApplication.java - The Spring Boot Application class generated with Spring Initializer. This class acts as the launching point for the application.
  • pom.xml - Contains all the dependencies needed to build this project. We will use Spring Boot Starter AOP.
  • Student.java - Student JPA Entity.
  • StudentRepository.java - Student JPA Repository. This is created using Spring Data JpaRepository.
  • StudentResource.java - Spring Rest Controller exposing all services on the student resource.
  • CustomizedResponseEntityExceptionHandler.java - Component to implement global exception handling and customize the response based on the exception type.
  • ErrorDetails.java - Response Bean to use when exceptions are thrown from the API.
  • StudentNotFoundException.java - Exception thrown from resources when the student is not found.
  • data.sql - Initial data for the student table. Spring Boot would execute this script after the tables are created from the entities.
  • Maven 3.0+ is your build tool.
  • Your favorite IDE. We use Eclipse.
  • JDK 1.8+

Complete Maven Project With Code Examples

Our GitHub repository has all the code examples.

What Is Validation?

You expect a certain format for the requests to your RESTful Service. You expect the elements of your request to have certain data types and certain domain constraints.

What if you get a request that does not meet these constraints?

Can I just return a generic message Something went wrong.. Is that good enough?

One of the core design principles for RESTful services is:

Think about the consumer

So, what should you do when something in the request is not valid?

You should return a proper error response:

  • A clear message indicating what went wrong, which field has an error and what are the accepted values, and what the consumer can do to fix the error.
  • Proper response status for a bad request.
  • Do not include sensitive information in the response.

Response Statuses for Validation Errors

The recommended response status for a validation error is, 400 - BAD REQUEST  

Bootstrapping a Project With a REST Resouce

In the previous article in the series, we set up a simple RESTful service with a resource exposing CRUD methods.

We will use the same example to discuss Exception Handling.

Default Validation With Spring Boot

Spring Boot provides a good default implementation for validation of RESTful Services. Let’s quickly look at the default Exception Handling features provided by Spring Boot.

Wrong Content Type

If you use the Content-Type application/xml and this is not supported by your application, Spring Boot, by default, returns a response status of 415 - Unsupported Media Type.

Invalid JSON Content

If you send invalid JSON content to a method expecting a body, you would get, 400 - Bad Request.

Valid JSON With Missing Elements

However, if you send a valid JSON structure with missing/invalid attributes/elements, the application will execute the request with whatever data is available.

The following request executes with a status of 201 Created. 

POST http://localhost:8080/students

Empty Request Content

The following request executes with a status of 201 Created.

POST http://localhost:8080/students

Request Content

You'll notice that the above request has an invalid attribute, name1.

This is the response when you fire a GET request to http://localhost:8080/students

[ { “id”: 1, “name”: null, “passportNumber”: null }, { “id”: 2, “name”: null, “passportNumber”: “A12345678” }, { “id”: 10001, “name”: “Ranga”, “passportNumber”: “E1234567” }, { “id”: 10002, “name”: “Ravi”, “passportNumber”: “A1234568” } ]

You can see that both the resources were created with ids 1 and 2 with nulls for values that were not available. Invalid elements/attributes are ignored.

Customizing Validations

To customize the validation, we will use Hibernate Validator, which is one of the implementations of the bean validation API.

We can get Hibernate Validator for free when we use Spring Boot Starter Web.

So, we can get started with implementing the validations.

Implementing Validations on the Bean

Let’s add a few validations to the Student bean. We are using @Size to specify the minimum length and also a message when a validation error occurs.

The Bean Validation API provides a number of such annotations. Most of these are self-explanatory:
  • DecimalMax
  • DecimalMin
  • Digits
  • Email
  • Future
  • FutureOrPresent
  • Max
  • Min
  • Negative
  • NegativeOrZero
  • NotBlank
  • NotEmpty
  • NotNull
  • Null
  • Past
  • PastOrPresent
  • Pattern
  • Positive
  • PositiveOrZero

Enabling Validation on the Resource

Simple. Add @Valid in addition to @RequestBody.

That’s it.

When you execute a request with attributes not matching the constraint, you get a 404 Bad Request status back.

Request

But the problem is that there are no details returned indicating what went wrong.

  • The consumer knows it's a bad request.
  • But, how do they know what went wrong? Which element did not pass the validation? What should the consumer do to fix it?

Customizing Validation Response

Let’s define a simple error response bean.

Let’s now define a @ControllerAdvice to handle validation errors. We do that by overriding the following method in the ResponseEntityExceptionHandler


To use ErrorDetails to return the error response, let’s define ControllerAdvice  as shown below.

When you execute a request with attributes not matching the constraint, you get a 404 Bad Request status back.

Request

You also get a Response Body indicating what is wrong!

Good Luck! You are all set now to customize the message based on your needs.

Complete Code Example

/pom.xml


/src/main/java/com/in28minutes/springboot/rest/example/exception/CustomizedResponseEntityExceptionHandler.java


/src/main/java/com/in28minutes/springboot/rest/example/exception/ErrorDetails.java


/src/main/java/com/in28minutes/springboot/rest/example/SpringBoot2RestServiceApplication.java


/src/main/java/com/in28minutes/springboot/rest/example/student/Student.java


/src/main/java/com/in28minutes/springboot/rest/example/student/StudentNotFoundException.java


/src/main/java/com/in28minutes/springboot/rest/example/student/StudentRepository.java


/src/main/java/com/in28minutes/springboot/rest/example/student/StudentResource.java


/src/main/resources/data.sql


/src/test/java/com/in28minutes/springboot/rest/example/SpringBoot2RestServiceApplicationTests.java


Published at DZone with permission of Ranga Karanam, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.


Comments