A comprehensive Spring Boot application demonstrating various validation techniques using Jakarta Bean Validation annotations.
- Overview
- Technologies Used
- Project Structure
- Getting Started
- API Endpoints
- Validation Rules
- Usage Examples
- Error Handling
- Video Tutorial
- Contributing
This project showcases the implementation of robust data validation in a Spring Boot REST API, featuring both standard Jakarta Bean Validation and advanced custom validation annotations. It demonstrates how to validate student information using built-in constraints, custom parameterized validators, and cross-field validation techniques, all with comprehensive error handling and meaningful error responses.
Key Features:
- π Standard Jakarta Bean Validation annotations
- π― Custom parameterized validation annotations (@MinimumAge)
- π Cross-field validation for data consistency (@AgeMatchesDateOfBirth)
- π¨ Global exception handling with structured error responses
- π Comprehensive validation rule documentation
- Java 21
- Spring Boot 3.5.5
- Spring Boot Starter Web - For REST API functionality
- Spring Boot Starter Validation - For Jakarta Bean Validation
- Lombok 1.18.38 - For reducing boilerplate code
- Maven - For dependency management and build automation
validation-demo/
βββ src/
β βββ main/
β β βββ java/com/learnwithiftekhar/validation_demo/
β β β βββ ValidationDemoApplication.java # Main Spring Boot application
β β β βββ Student.java # Student model with validation annotations
β β β βββ StudentController.java # REST controller for student operations
β β β βββ validation/ # Custom validation package
β β β βββ CustomValidationException.java # Global exception handler
β β β βββ MinimumAge.java # Custom minimum age validation annotation
β β β βββ MinimumAgeValidator.java # Validator for minimum age constraint
β β β βββ AgeMatchesDateOfBirth.java # Cross-field validation annotation
β β β βββ AgeValidator.java # Validator for age/DOB consistency
β β βββ resources/
β β βββ application.properties # Application configuration
β βββ test/
β βββ java/com/learnwithiftekhar/validation_demo/
β βββ ValidationDemoApplicationTests.java
βββ pom.xml # Maven configuration
βββ README.md # Project documentation
- Java 21 or higher
- Maven 3.6+ (or use the included Maven wrapper)
-
Clone the repository
git clone https://github.com/learnwithiftekhar/spring-boot-data-validation.git cd spring-boot-data-validation -
Build the project
./mvnw clean compile
-
Run the application
./mvnw spring-boot:run
-
Alternative: Run with Java
./mvnw clean package java -jar target/validation-demo-0.0.1-SNAPSHOT.jar
The application will start on http://localhost:8080
Creates/validates a student record.
Request Body: Student JSON object
Response: Validated Student object or validation errors
Content-Type: application/json
This project implements advanced custom validation annotations beyond standard Jakarta Bean Validation:
A parameterized validation annotation that allows specifying a minimum age requirement.
- Target: Fields (applied to
dateOfBirth) - Parameter:
value- minimum age in years - Validator:
MinimumAgeValidator.class - Usage:
@MinimumAge(value = 17, message = "Student must be at least 17 years old.")
A class-level validation that ensures consistency between age and dateOfBirth fields.
- Target: Class level (applied to entire
Studentclass) - Validator:
AgeValidator.class - Purpose: Cross-field validation to prevent data inconsistencies
- Usage:
@AgeMatchesDateOfBirth
- MinimumAgeValidator: Calculates age from date of birth and validates against minimum requirement
- AgeValidator: Performs cross-field validation ensuring the provided age matches the calculated age from date of birth
The Student model includes comprehensive validation rules:
| Field | Validation Rules | Error Messages |
|---|---|---|
| Class Level | β’ @AgeMatchesDateOfBirth (Cross-field validation) | β’ "The provided age does not match the date of birth" |
studentId |
β’ Required (not blank) β’ Pattern: ^S\d{5}$ |
β’ "Student ID is required." β’ "Student id must be in the format 'S' followed by 5 digits (e.g. S12345)" |
firstName |
β’ Required (not blank) | β’ "First Name is required." |
middleName |
β’ Cannot be null | β’ "Middle Name cannot be null." |
lastName |
β’ Required (not blank) | β’ "Last Name is required." |
age |
β’ Required β’ Min: 17 β’ Max: 100 |
β’ "Age is required." β’ "Student must be at least 17 years old" β’ "Student age must not be greater than 100 years." |
dateOfBirth |
β’ Required β’ Must be in the past β’ @MinimumAge(17) (Custom validation) |
β’ "Date of birth is required." β’ "Date of birth must be in the past." β’ "Student must be at least 17 years old." |
expectedGraduationDate |
β’ Required β’ Must be in the future |
β’ "Expected graduation date is required." β’ "Graduation date must be in the future." |
email |
β’ Required β’ Valid email format |
β’ "Email address is required." β’ "Please provide valid email address." |
enrolledCourses |
β’ Cannot be empty | β’ "Student must enrolled in at least one course." |
gpa |
β’ Required β’ Min: 0.0 β’ Max: 4.0 β’ Format: X.XX |
β’ "GPA is required." β’ "GPA must be at least 0.0" β’ "GPA must not exceed 4.0" β’ "GPA must have at most 1 integer and 2 fraction digits." |
curl -X POST http://localhost:8080/ \
-H "Content-Type: application/json" \
-d '{
"studentId": "S12345",
"firstName": "John",
"middleName": "Michael",
"lastName": "Doe",
"age": 20,
"dateOfBirth": "2003-05-15",
"expectedGraduationDate": "2026-06-15",
"email": "john.doe@example.com",
"enrolledCourses": ["Computer Science 101", "Mathematics"],
"gpa": "3.75"
}'Response (200 OK):
{
"studentId": "S12345",
"firstName": "John",
"middleName": "Michael",
"lastName": "Doe",
"age": 20,
"dateOfBirth": "2003-05-15",
"expectedGraduationDate": "2026-06-15",
"email": "john.doe@example.com",
"enrolledCourses": ["Computer Science 101", "Mathematics"],
"gpa": 3.75
}curl -X POST http://localhost:8080/ \
-H "Content-Type: application/json" \
-d '{
"studentId": "12345",
"firstName": "",
"age": 15,
"email": "invalid-email",
"gpa": "5.0"
}'Response (400 Bad Request):
{
"studentId": "Student id must be in the format 'S' followed by 5 digits (e.g. S12345)",
"firstName": "First Name is required.",
"middleName": "Middle Name cannot be null.",
"lastName": "Last Name is required.",
"age": "Student must be at least 17 years old",
"dateOfBirth": "Date of birth is required.",
"expectedGraduationDate": "Expected graduation date is required.",
"email": "Please provide valid email address.",
"enrolledCourses": "Student must enrolled in at least one course.",
"gpa": "GPA must not exceed 4.0"
}The application includes a global exception handler (CustomValidationException) that:
- Catches
MethodArgumentNotValidExceptionfor validation errors - Returns structured JSON responses with field-specific error messages
- Uses HTTP status code 400 (Bad Request) for validation failures
- Provides clear, actionable error messages for each validation failure
Error response format:
{
"fieldName": "error message",
"anotherField": "another error message"
}Run the tests using:
./mvnw testThis project is featured in a comprehensive YouTube tutorial that walks through the implementation step by step:
πΊ Spring Boot Data Validation Tutorial
The tutorial covers:
- Setting up Spring Boot with validation dependencies
- Creating validation annotations for different data types
- Implementing custom error handling
- Testing validation scenarios with real examples
- Best practices for data validation in Spring Boot
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow Java naming conventions
- Add appropriate validation annotations for new fields
- Include comprehensive error messages
- Update tests when adding new features
- Ensure all tests pass before submitting
This project is created for educational purposes to demonstrate Spring Boot validation techniques.
Learn with Iftekhar
- GitHub: @learnwithiftekhar
This project demonstrates best practices for data validation in Spring Boot applications using Jakarta Bean Validation annotations.