Spring Boot Validation: Jakarta Validators and Spring-Specific Validators.

 

Jakarta Validation (formerly Bean Validation) provides a powerful way to validate data in Java applications, including Spring Boot projects. It includes various built-in constraints and allows for the creation of custom validators. This guide explores built-in validators with practical Java code examples and demonstrates how to define a custom validator that returns error messages using message.properties.

Spring Boot Validation: Jakarta Validators and Spring-Specific Validators.



Pom Dependencies

To enable validation in a Spring Boot application, you need to include the necessary dependencies in your pom.xml file. These dependencies provide support for Jakarta Validation and Spring Boot's built-in validation capabilities. In this section, we will list the essential dependencies and explain their purpose to ensure seamless integration and robust data validation.

    <properties>

        <java.version>22</java.version>

        <spring.boot.version>3.4.2</spring.boot.version>

    </properties>

    <dependencies>

        <!-- Spring Boot Starter Web (to use REST Controllers) -->

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-web</artifactId>

        </dependency>

        <!-- Spring Boot Starter Validation (includes Jakarta Validation and Hibernate Validator) -->

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-validation</artifactId>

        </dependency>

        <!-- Spring Boot Starter Test (for testing validation logic) -->

    </dependencies>


Validators in Jakarta Lib Bean Validator


Here is the complete list of available validators in Jakarta Validation (Bean Validation 3.0).

@NotNull 

Description: Ensures that the attribute value is not null. However, it can be an empty string, an empty list, etc. Example:

@NotNull(message = "{NotNull.error}")
private String username;

@NotEmpty 

Description: Ensures that the value is neither null nor an empty string/list/array ("", [], {}). Example:

@NotEmpty
private String email;

@NotBlank 

Description: Ensures that the string is not null, empty, or composed only of whitespace. Example:

@NotBlank
private String fullName;

@Size(min, max) 

Description: Checks that the length of the string, list, or array is between the specified min and max values. Example:

@Size(min = 3, max = 10)
private String nickname;

@Min(value) 

Description: Ensures that a numerical value is greater than or equal to the specified value. Example:

@Min(18)
private int age;

@Max(value) 

Description: Ensures that a numerical value is less than or equal to the specified value. Example:

@Max(100)
private int discountPercentage;

@Positive 

Description: The value must be strictly greater than zero. Example:

@Positive
private int quantity;

@PositiveOrZero 

Description: The value must be greater than or equal to zero. Example:

@PositiveOrZero
private int stock;

@Negative 

Description: The value must be strictly less than zero. Example:

@Negative
private int temperature;

@NegativeOrZero 

Description: The value must be less than or equal to zero. Example:

@NegativeOrZero
private int balance;

@Email 

Description: Ensures that the string is a valid email address. Example:

@Email
private String email;

@Pattern(regexp) 

Description: Ensures that the string matches a specified regular expression. Example: Accepts only 10-digit phone numbers.

@Pattern(regexp = "\\d{10}")
private String phoneNumber;

@Past 

Description: The value must be a past date. Example:

@Past
private LocalDate birthDate;

@PastOrPresent 

Description: The value must be a past date or today’s date. Example:

@PastOrPresent
private LocalDateTime lastUpdate;

@Future 

Description: The value must be a future date. Example:

@Future
private LocalDate reservationDate;

@FutureOrPresent 

Description: The value must be a future date or today’s date. Example:

@FutureOrPresent
private LocalDateTime startTime;

@Digits(integer, fraction) 

Description: Specifies the maximum number of digits before and after the decimal point. Example: A number with a maximum of 5 integer digits and 2 decimal places.

@Digits(integer = 5, fraction = 2)
private BigDecimal price;

@CreditCardNumber 

Description: Validates a credit card number (available in Hibernate Validator). Example:

@CreditCardNumber
private String creditCard;

@Length(min, max) 

Description: Validates the length of a string (available in Hibernate Validator). Example:

@Length(min = 5, max = 15)
private String password;

@URL 

Description: Validates a string as a correct URL (available in Hibernate Validator). Example:

@URL
private String website;

@Range(min, max) 

Description: The value must be between min and max (available in Hibernate Validator). Example:

@Range(min = 1, max = 100)
private int score;

@Valid 

Description: Indicates that the value must be validated recursively if it is a complex object. Example:

@Valid
private Address address;

Additional Validators in Hibernate Validator

@ScriptAssert(lang, script, alias)

Description: Allows executing a script to validate an object. Example: Password and confirmation must match.

@ScriptAssert(lang = "javascript", script = "_this.password.equals(_this.confirmPassword)")

public class User {

    private String password;

    private String confirmPassword;

}


@SafeHtml (Deprecated)

Description: Ensured content was free from harmful code (XSS). Alternative: Use ESAPI or other sanitization libraries.

@EAN

Description: Validates an EAN (European Article Number) barcode. Example:

@EAN

private String productCode;

@ISBN

Description: Validates an ISBN code (for books). Example:

@ISBN

private String bookCode;

@LuhnCheck

Description: Ensures a number follows the Luhn algorithm (used for credit cards). Example:

@LuhnCheck

private String creditCardNumber;

@Mod10Check and @Mod11Check

Description: Validates numbers using Mod10 and Mod11 checksum algorithms. Example:

@Mod10Check

private String iban;

@Currency

Description: Ensures a value is a valid currency code (ISO 4217). Example:

@Currency

private String currencyCode;

@UUID

Description: Ensures a string is a valid UUID. Example:

@UUID

private String userId;

@UniqueElements

Description: Ensures a list contains unique elements. Example:

@UniqueElements

private List<String> emails;


Spring Valid annotation

Spring provides additional options with Spring Boot Validation.


@Valid


Description: Allows validation of method parameters in a controller or service. 


Example: 


@RestController

public class UserController {

    @PostMapping("/users")

    public ResponseEntity<String> createUser(@Valid @RequestBody User user) {

        return ResponseEntity.ok("User created");

    }

}

Custom Validation

Defining the Annotation

import jakarta.validation.Constraint;

import jakarta.validation.Payload;

import java.lang.annotation.*;


@Documented

@Constraint(validatedBy = UppercaseValidator.class)

@Target({ElementType.FIELD})

@Retention(RetentionPolicy.RUNTIME)

public @interface Uppercase {

    String message() default "{uppercase.error}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

}


Implementing the Validator

import jakarta.validation.ConstraintValidator;

import jakarta.validation.ConstraintValidatorContext;


public class UppercaseValidator implements ConstraintValidator<Uppercase, String> {

    @Override

    public boolean isValid(String value, ConstraintValidatorContext context) {

        return value != null && value.equals(value.toUpperCase());

    }

}


Using the Validator

public class User {

    @Uppercase

    private String username;

}

Error Message Definition

In message.properties file:

uppercase.error = The field must contain only uppercase letters.


Defining Error Messages in message.properties

To customize messages in built-in validators, modify message.properties:

NotNull.error = This field cannot be null.

NotEmpty.error = This field cannot be empty.

NotBlank.error = This field cannot be blank.

Size.error = The length must be between {min} and {max} characters.

Pattern.error = Invalid format.

Email.error = Please enter a valid email address.

Min.error = The value must be at least {value}.

Max.error = The value must be at most {value}.

Positive.error = The value must be positive.

PositiveOrZero.error = The value must be zero or greater.

Negative.error = The value must be negative.

NegativeOrZero.error = The value must be zero or lower.

Digits.error = The number must have at most {integer} integer digits and {fraction} fractional digits.

Past.error = The date must be in the past.

PastOrPresent.error = The date must be in the past or today.

Future.error = The date must be in the future.

FutureOrPresent.error = The date must be in the future or today.

Length.error = The length must be between {min} and {max} characters.

CreditCardNumber.error = Invalid credit card number.

URL.error = Invalid URL.

UniqueElements.error = The list must contain unique elements.

Conclusion

Jakarta Validation provides a robust system for data validation. In this guide, we explored built-in validators, their examples, and how to create a custom validator with message properties. These validation techniques help maintain data integrity and user input validation in enterprise applications. 🚀

Reference



About Me

I am passionate about IT technologies. If you’re interested in learning more or staying updated with my latest articles, feel free to connect with me on:

Feel free to reach out through any of these platforms if you have any questions!

I am excited to hear your thoughts! 👇

Comments

Popular posts from this blog

Monitoring and Logging with Prometheus: A Practical Guide

Creating a Complete CRUD API with Spring Boot 3: Authentication, Authorization, and Testing

Logging in Spring Boot 3: Best Practices for Configuration and Implementation