Core Java

How to Validate A Value List In Spring

Validation is a crucial aspect of web applications, ensuring that input data conforms to expected formats and rules before processing. In a Spring Boot application, we often deal with collections of objects, such as lists of students in an API request. This article demonstrates how to validate a value bearing list in Spring Boot using Jakarta Validation.

1. Project Setup

Ensure you have the necessary dependencies in your pom.xml if you are using Maven:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

This dependency ensures that Hibernate Validator, the default validation implementation, is available in the project.

2. Creating the Model

Let’s define a Student model with validation annotations:

public class Student {
    
    @NotBlank(message = "Name cannot be blank")
    @Size(min = 3, max = 50, message = "Name must be between 3 and 50 characters")
    private String name;
    
    @NotBlank(message = "Email cannot be blank")
    @Pattern(
        regexp = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$",
        message = "Invalid email format"
    )
    private String email;

    public Student(String name, String email) {
        this.name = name;
        this.email = email;
    }   

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

In this class:

  • @NotBlank ensures that name and email fields are not empty.
  • @Size enforces a character limit on the name field.
  • @Pattern applies a regex pattern to validate email format.

3. Creating a DTO for Student List Validation

To validate a list of students, we create a Data Transfer Object (DTO) and use @Valid on the list.

public class StudentListRequest {
    
    @NotEmpty(message = "Student list cannot be empty")
    @Valid
    private List<Student> students;

    public StudentListRequest() {}

    public StudentListRequest(List<Student> students) {
        this.students = students;
    }

    public List<Student> getStudents() {
        return students;
    }

    public void setStudents(List<Student> students) {
        this.students = students;
    }
}

The @NotEmpty annotation ensures that the list contains at least one student, preventing empty submissions. The @Valid annotation triggers validation for each Student object inside the list, ensuring that all students meet the defined constraints. Using a DTO class, we ensure that validation is applied at the request level, improving data integrity and making the API more robust.

4. Implementing the Controller

Next, we create a REST controller to handle student list submissions.

@RestController
@RequestMapping("/students")
@Validated
public class StudentController {

    @PostMapping("/validate")
    public ResponseEntity<String> validateStudents(@Valid @RequestBody StudentListRequest studentListRequest) {
        return ResponseEntity.ok("Validation successful! Received " + studentListRequest.getStudents().size() + " students.");
    }
}

The validateStudents method is mapped to @PostMapping("/validate"), defining it as a POST API endpoint. It uses @Valid on StudentListRequest to trigger validation for the incoming request. If validation passes, the method returns a success response, confirming the number of students received.

5. Handling Validation Errors

By default, Spring returns a generic validation error message. To customize error handling, we create an exception handler.

@RestControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Map<String, String>> handleValidationExceptions(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getFieldErrors().forEach(error -> 
            errors.put(error.getField(), error.getDefaultMessage()));

        return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
    }  
}

The @RestControllerAdvice annotation enables global exception handling, allowing centralized error management across the application. The @ExceptionHandler(MethodArgumentNotValidException.class) specifically catches validation errors that occur when request data fails to meet defined constraints. Within the exception handler method, field errors are extracted from the binding result and formatted into a structured JSON response, providing clear and user-friendly validation feedback.

5.1 Testing the Validation

To test the validation of the student list API using curl, we can send a POST request to the following URL:

Valid Request

curl -X POST http://localhost:8080/students/validate \
     -H "Content-Type: application/json" \
     -d '{
           "students": [
             { "name": "John Doe", "email": "john.doe@example.com" },
             { "name": "Alice Smith", "email": "alice.smith@example.com" }
           ]
         }'

Expected Response for Valid Input:

Validation successful! Received 2 students.

Invalid Request (Name Too Short and Invalid Email Format)

curl -X POST http://localhost:8080/students/validate \
     -H "Content-Type: application/json" \
     -d '{
           "students": [
             { "name": "Jo", "email": "invalid-email" },
             { "name": "", "email": "alice@example" }
           ]
         }'

Expected Response for Invalid Input:

{"students[1].name":"Name must be between 3 and 50 characters",
"students[0].email":"Invalid email format",
"students[0].name":"Name must be between 3 and 50 characters"}

The first student’s name is too short (“Jo”), violating the @Size constraint, and their email (“invalid-email”) does not match the required pattern, triggering the @Pattern validation. The second student has an empty name (“”), which violates the @NotBlank constraint, and their email (“alice@example”) is improperly formatted due to the missing domain extension, failing the @Pattern validation.

As a result, the response provides a detailed list of validation errors for each student, ensuring clear feedback on what needs to be corrected. This curl test confirms that Spring Boot’s validation is correctly enforcing the constraints.

6. Conclusion

In this article, we explored how to validate a list of students in a Spring Boot application using @Valid and regex constraints. We implemented field-level validation for names and emails using @NotBlank, @Size, and @Pattern, ensuring that input data adheres to defined rules. By using a DTO, we applied validation at the request level, and with a global exception handler, we provided structured error responses.

7. Download the Source Code

This article covered how to validate a list of value in Java Spring.

Download
You can download the full source code of this example here: how to validate a list of value in Java Spring

Omozegie Aziegbe

Omos Aziegbe is a technical writer and web/application developer with a BSc in Computer Science and Software Engineering from the University of Bedfordshire. Specializing in Java enterprise applications with the Jakarta EE framework, Omos also works with HTML5, CSS, and JavaScript for web development. As a freelance web developer, Omos combines technical expertise with research and writing on topics such as software engineering, programming, web application development, computer science, and technology.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button