Spring Boot Tutorial

Spring Boot - Software Setup and Configuration (STS/Eclipse/IntelliJ)

Prerequisite (Spring Core Concepts)

Spring Boot Core

Spring Boot with REST API

Spring Boot with Database and Data JPA

Spring Boot with Kafka

Spring Boot with AOP

Spring Boot - Validation using Hibernate Validator

Hibernate Validator is the reference implementation of the Jakarta Bean Validation specification (formerly Java Bean Validation), which allows developers to express and validate application-level constraints on Java beans. With Spring Boot, integrating Hibernate Validator is straightforward, enabling automatic validation and easy handling of validation errors.

Here's how you can set up validation using Hibernate Validator in a Spring Boot application:

1. Add Dependencies

If you have spring-boot-starter-web in your project, Hibernate Validator is already included. Otherwise, you can add it directly:

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

<!-- OR if you just need Hibernate Validator -->

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>your_version_here</version>
</dependency>

2. Add Constraints to Your Model/DTO

Annotate fields in your model or DTO with validation constraints:

public class UserDTO {

    @NotBlank(message = "Username is mandatory")
    private String username;

    @Email(message = "Email should be valid")
    private String email;

    @Size(min = 8, message = "Password should have at least 8 characters")
    private String password;

    // getters and setters
}

3. Validate in Controller

Your annotated beans will automatically be validated when used in a controller method with the @Valid annotation:

@RestController
@RequestMapping("/users")
public class UserController {

    @PostMapping("/register")
    public ResponseEntity<?> registerUser(@Valid @RequestBody UserDTO userDTO) {
        // Handle the registration logic
        return ResponseEntity.ok("User registered successfully");
    }
}

4. Handle Validation Errors

You can handle validation errors using Spring's exception handling mechanisms. A common way is to use @ExceptionHandler:

@RestControllerAdvice
public class CustomExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<List<String>> handleValidationExceptions(MethodArgumentNotValidException ex) {
        List<String> errors = ex.getBindingResult()
            .getAllErrors().stream()
            .map(DefaultMessageSourceResolvable::getDefaultMessage)
            .collect(Collectors.toList());
        return ResponseEntity.badRequest().body(errors);
    }
}

When a validation error occurs, the custom exception handler will capture it and return a list of error messages.

5. Customize Error Messages

You can customize error messages in multiple ways:

  • Directly in the annotation: As shown in the UserDTO example above.

  • Using a message properties file: Create a messages.properties file in the src/main/resources directory and use keys for messages:

    user.email.invalid=Provided email is invalid!
    

    Then, in the model, use the key:

    @Email(message = "{user.email.invalid}")
    private String email;
    

6. Advanced Constraints

Hibernate Validator provides a rich set of built-in constraints, and you can also define custom constraints if needed. This way, you can create complex validation logic tailored to your application's requirements.

With these steps, you can effectively set up validation in your Spring Boot application, ensuring that the data your application processes are both consistent and valid.

  1. Configuring Hibernate Validator in Spring Boot:

    • Description: Hibernate Validator is automatically configured in a Spring Boot application when the necessary dependencies are included. Additional configuration can be done in application.properties or application.yml.
    • Code:
      # application.yml
      spring:
        jpa:
          hibernate:
            ddl-auto: validate
        messages:
          basename: validationMessages
      
  2. Using annotations for field-level validation in Spring Boot:

    • Description: Leverage annotations from the javax.validation.constraints package for field-level validation, such as @NotNull, @Size, and @Email.
    • Code:
      public class User {
          @NotNull
          @Size(min = 2, max = 50)
          private String username;
      
          @Email
          private String email;
          // Other fields and methods
      }
      
  3. Custom constraints and validation groups with Hibernate Validator in Spring Boot:

    • Description: Create custom validation constraints and groups to tailor validation rules to specific use cases.
    • Code:
      @Target({ElementType.FIELD})
      @Retention(RetentionPolicy.RUNTIME)
      @Constraint(validatedBy = CustomValidator.class)
      public @interface CustomConstraint {
          String message() default "Custom validation failed";
          Class<?>[] groups() default {};
          Class<? extends Payload>[] payload() default {};
      }
      
  4. Cross-field validation in Spring Boot with Hibernate Validator:

    • Description: Validate multiple fields together using cross-field validation annotations like @ScriptAssert or by creating custom cross-field validators.
    • Code:
      public class User {
          @NotBlank
          private String password;
      
          @NotBlank
          private String confirmPassword;
          // Other fields and methods
      }
      
  5. Validating method parameters and return values in Spring Boot:

    • Description: Apply validation to method parameters and return values using annotations like @Validated on the method or by using parameter-level annotations.
    • Code:
      @Service
      @Validated
      public class UserService {
          public User createUser(@NotNull @Valid User user) {
              // Business logic
          }
      }
      
  6. Integration of Hibernate Validator with Spring Boot controllers:

    • Description: Integrate Hibernate Validator with Spring Boot controllers by using @Valid on method parameters to trigger validation.
    • Code:
      @RestController
      public class UserController {
          @PostMapping("/users")
          public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
              // Controller logic
          }
      }
      
  7. Error handling and displaying validation messages in Spring Boot:

    • Description: Handle validation errors by customizing error messages, creating custom exception handlers, and displaying error messages in the UI.
    • Code:
      @ControllerAdvice
      public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
          @ExceptionHandler(MethodArgumentNotValidException.class)
          public ResponseEntity<Object> handleValidationErrors(MethodArgumentNotValidException ex,
                                                              HttpHeaders headers,
                                                              HttpStatus status,
                                                              WebRequest request) {
              // Handle and customize validation errors
          }
      }
      
  8. Testing validation in Spring Boot applications with Hibernate Validator:

    • Description: Write tests to validate that the validation constraints work as expected, both at the unit and integration levels.
    • Code:
      @RunWith(SpringRunner.class)
      @SpringBootTest
      public class UserValidationTest {
          @Autowired
          private Validator validator;
      
          @Test
          public void testUsernameNotBlank() {
              User user = new User();
              user.setUsername(""); // Blank username
              Set<ConstraintViolation<User>> violations = validator.validate(user);
              // Assert validation results
          }
      }