Core Java

Java Validation List Annotations

Java Validation List Annotations empower developers to validate lists of elements within applications. By specifying rules and constraints, these annotations enhance data integrity, ensuring accurate processing. Let us explore how to implement these annotations for robust validation, error prevention, and streamlined data management in Java applications.

1. Introduction

In the Jakarta Bean Validation API (part of Jakarta EE, previously Java EE), several built-in annotations provide validation constraints for various data types. These annotations can be used individually or as part of composed annotations to define validation rules for Java objects. Some of these annotations include @Size, @Pattern, @Min, @Max, @AssertTrue, and @Future. These list-valued constraints are applied to collections or arrays, allowing developers to specify multiple validation rules for the same data attribute.

AnnotationUsageDescription
@Size.List@Size.List({@Size(min = 2), @Size(max = 10)})Validates that the size of the list falls within the specified range.
@Pattern.List@Pattern.List({@Pattern(regexp = "[a-zA-Z]+"), @Pattern(regexp = "[0-9]+")})Validates that the elements in the list match any of the specified regular expression patterns.
@Min.List@Min.List({@Min(value = 18), @Min(value = 21)})Validates that the elements in the list are greater than or equal to the specified minimum value.
@Max.List@Max.List({@Max(value = 100), @Max(value = 150)})Validates that the elements in the list are less than or equal to the specified maximum value.
@AssertTrue.List@AssertTrue.List({@AssertTrue, @AssertTrue})Validates that the elements in the list are all true when evaluated.
@Future.List@Future.List({@Future, @Future})Validates that the elements in the list represent dates in the future.

2. Understanding @Size.List Annotation

@Size.List is an annotation in Jakarta Bean Validation that allows you to apply multiple @Size constraints to a collection or array. This is useful when you want to ensure that a list or array meets multiple size-related criteria simultaneously. Let’s say you have a Java class representing a book with two lists: one for authors and one for keywords. You want to enforce the following rules:

  • The list of authors must have between 1 and 5 elements.
  • Each author’s name must be between 2 and 50 characters long.
  • The list of keywords must have between 3 and 10 elements.
  • Each keyword must be between 1 and 20 characters long.

Here’s how you can use @Size.List to achieve this:

Book.java

package com.jcg.example;

import jakarta.validation.constraints.Size;
import jakarta.validation.constraints.NotNull;
import java.util.List;

public class Book {

    @NotNull
    @Size.List({
        @Size(min = 1, max = 5, message = "Number of authors must be between 1 and 5"),
        @Size(min = 2, max = 50, message = "Author's name must be between 2 and 50 characters")
    })
    private List<String> authors;

    @NotNull
    @Size.List({
        @Size(min = 3, max = 10, message = "Number of keywords must be between 3 and 10"),
        @Size(min = 1, max = 20, message = "Keyword must be between 1 and 20 characters")
    })
    private List<String> keywords;

    // Getters and setters
}

In this example, @Size.List is applied to both the authors and keywords lists. For the authors list, it specifies that the list must contain between 1 and 5 elements, and each author’s name within the list must be between 2 and 50 characters long. For the keywords list, it specifies that the list must contain between 3 and 10 elements, and each keyword must be between 1 and 20 characters long. These constraints ensure that instances of the Book class meet the specified size criteria for both the authors and keywords lists simultaneously.

3. Understanding @Pattern.List Annotation

The @Pattern.List annotation in Jakarta Bean Validation API allows you to apply multiple regular expression patterns to a field. Each pattern in the list is validated individually. Consider a class representing user passwords with specific pattern requirements:

User.java

package com.jcg.example;

import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Pattern.List;

public class User {
    <span class="note">// Password must contain at least 1 uppercase letter, 1 lowercase letter,</span>
    <span class="note">// 1 digit, and be at least 8 characters long.</span>
    <span class="note">// OR it should be a strong passphrase with at least 12 characters.</span>
    @Pattern.List({
        @Pattern(regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{8,}$", message = "Weak Password"),
        @Pattern(regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{12,}$", message = "Strong Passphrase")
    })
    private String password;
}

In this example, the @Pattern.List annotation is used to define two patterns for the password field. The password must meet either the “Weak Password” or “Strong Passphrase” criteria.

Note: Regular expressions are used to define complex patterns. In this example, the regular expressions check for specific character combinations (uppercase, lowercase, digits) and minimum length.

4. Understanding @Min.List and @Max.List Annotations

The @Min.List and @Max.List annotations in Jakarta Bean Validation API allow you to apply multiple minimum and maximum value constraints respectively to a field. Each constraint in the list is validated individually. Consider a class representing product quantities with specific requirements:

Product.java

package com.jcg.example;

import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min.List;
import jakarta.validation.constraints.Max.List;

public class Product {
    <span class="note">// Quantity must be at least 1 and at most 100 for standard products.</span>
    <span class="note">// For premium products, quantity must be at least 10 and at most 500.</span>
    @Min.List({
        @Min(value = 1, message = "Minimum quantity for standard product is 1"),
        @Min(value = 10, message = "Minimum quantity for premium product is 10")
    })
    @Max.List({
        @Max(value = 100, message = "Maximum quantity for standard product is 100"),
        @Max(value = 500, message = "Maximum quantity for premium product is 500")
    })
    private int quantity;
}

In this example, the @Min.List annotation specifies two constraints for the minimum quantity: one for standard products and one for premium products. Similarly, the @Max.List annotation sets different maximum quantity limits for standard and premium products.

Note: Multiple constraints are applied based on the type of product. Jakarta Bean Validation ensures that the quantity adheres to the specified limits for each product type.

5. Understanding @AssertTrue.List Annotation

The @AssertTrue.List annotation in Jakarta Bean Validation API allows you to apply multiple @AssertTrue constraints to a field. Each constraint in the list is validated individually. Consider a class representing a user profile with specific requirements:

UserProfile.java

package com.jcg.example;

import jakarta.validation.constraints.AssertTrue;
import jakarta.validation.constraints.AssertTrue.List;

public class UserProfile {
    private boolean isTermsAccepted;
    private boolean isAgeAbove18;

    <span class="note">// User must accept terms and conditions.</span>
    <span class="note">// User must be above 18 years old.</span>
    @AssertTrue.List({
        @AssertTrue(message = "Please accept the terms and conditions"),
        @AssertTrue(message = "You must be 18 or older to register")
    })
    public boolean isValidProfile() {
        return isTermsAccepted && isAgeAbove18;
    }

    <span class="note">// Getters and setters for isTermsAccepted and isAgeAbove18 fields</span>
}

In this example, the @AssertTrue.List annotation is used to define two conditions for the isValidProfile() method. The user must accept the terms and conditions, and the user must be 18 or older. Each condition is enforced with a separate @AssertTrue constraint.

Note: The isValidProfile() method combines multiple conditions that need to be true for a valid user profile. Jakarta Bean Validation ensures that each condition is individually met before validating the combined result.

6. Understanding @Future.List Annotation

The @Future.List annotation in Jakarta Bean Validation API allows you to apply multiple @Future constraints to a field, ensuring that the dates are in the future. Each constraint in the list is validated individually. Consider a class representing events with specific date requirements:

Event.java

package com.jcg.example;

import jakarta.validation.constraints.Future;
import jakarta.validation.constraints.Future.List;
import java.util.Date;

public class Event {
    private Date eventDate;
    private Date registrationEndDate;

    <span class="note">// Event date and registration end date must be in the future.</span>
    @Future.List({
        @Future(message = "Event date must be in the future"),
        @Future(message = "Registration end date must be in the future")
    })
    public boolean areDatesValid() {
        Date currentDate = new Date();
        return eventDate.after(currentDate) && registrationEndDate.after(currentDate);
    }

    <span class="note">// Getters and setters for eventDate and registrationEndDate fields</span>
}

In this example, the @Future.List annotation is used to define two @Future constraints for the areDatesValid() method. The method checks if the event date and registration end date are in the future. Each date is individually validated against the current date before validating the combined result.

Note: The areDatesValid() method combines multiple date conditions that need to be true for valid event dates. Jakarta Bean Validation ensures that each date is individually validated before validating the combined result.

7. Conclusion

Jakarta Bean Validation provides a powerful set of annotations for enforcing data integrity and accuracy in Java applications. We explored several key annotations, including @Size.List, @Pattern.List, @Min.List, @Max.List, @AssertTrue.List, and @Future.List.

With @Size.List, developers can ensure that collections or arrays meet multiple size-related criteria simultaneously. The @Pattern.List annotation allows the application of multiple regular expression patterns to a field, ensuring complex character combinations are validated.

For numeric values, @Min.List and @Max.List annotations enable developers to enforce multiple minimum and maximum value constraints. The @AssertTrue.List annotation offers flexibility in enforcing multiple boolean conditions for a single field or method, ensuring complex validation scenarios are accurately handled.

Additionally, the @Future.List annotation provides an efficient way to enforce multiple future date constraints, allowing accurate validation of future dates in Jakarta Bean Validation.

These annotations empower developers to define specific validation rules for diverse scenarios, enhancing the robustness and reliability of Java applications. By leveraging Jakarta Bean Validation annotations, developers can ensure that their data meets precise criteria, contributing to the overall quality and integrity of their software solutions.

Yatin

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

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

0 Comments
Inline Feedbacks
View all comments
Back to top button