DEV Community

Cover image for Validation on Spring
Martin Klestil
Martin Klestil

Posted on

Validation on Spring

Invalid inputs are the root of all evil! Or would you run your coffee maker on rocks?

How to start ?

We need the dependency:

<dependency> 
<groupId>org.springframework.boot</groupId> 
<artifactId>spring-boot-starter-validation</artifactId> 
</dependency>
Enter fullscreen mode Exit fullscreen mode

When do we validate?

As a rule of thumb for REST APIs: As soon as a controller method accepts a @RequestBody, it must be preceded by a @Valid!

Valid

@Valid (Standard Jakarta Validation): Placed on method parameters (like @RequestBody) or fields to trigger validation of nested objects.

Validated

It is a Spring-specific annotation. It is used at the class level when you want to validate @PathVariable or @RequestParam directly in the controller (e.g., @Min(1) Long id), or for validation groups.

Which endpoints are we validating?

  • Post Because the client send use new data.
  • Put / Patch When updating, the client also sends the modified data in the body. New values must also be checked for completeness and compliance with the rules (no stones, only water).

Why not GET or DELETE?

A GET request typically does not include a JSON body. We are simply requesting data.
When deleting a resource, we usually identify it by a unique ID, no JSON is sent along with the request either.

Validation Annotations

Spring Boot’s validation system supports all standard JSR-380 annotations:

  • @NotNull Field cannot be null.
  • @NotBlank String must not be null and must contain at least one non-whitespace character.
  • @Size Validates string length or collection size.
  • @Email Checks for a valid email format.
  • @Min, @Max Ensures numeric bounds.
  • @Positive, @Negative Checks numeric sign.
  • @Past, @FutureValidates dates relative to the present.

Example

First, define the validation constraints on your data object (ideally a DTO, or the Entity in smaller projects):

@Entity
@Table(name = "tasks")
public class Task {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotBlank(message = "Title cannot be blank")
    @Size(min = 3, max = 100, message = "Title must be between 3 and 100 characters")
    private String title;

    @NotBlank(message = "Description cannot be blank")
    @Size(min = 5, max = 500, message = "Description must be between 5 and 500 characters")
    private String description;

    // Getters and Setters
}
Enter fullscreen mode Exit fullscreen mode

Pro-Tip: Use DTOs instead of validating entities directly in real-world apps

Controller

@PostMapping("/projects/{projectId}/tasks")
public ResponseEntity<Task> createTask(
        @PathVariable Long projectId, 
        @Valid @RequestBody Task task) {

    Task createdTask = taskService.createTask(projectId, task);
    return ResponseEntity.status(HttpStatus.CREATED).body(createdTask);
}
Enter fullscreen mode Exit fullscreen mode

What happens here?

By placing ´@valid´ before @RequestBody, you instruct Spring Boot to check the incoming JSON payload against all constraints BEFORE executing the controller method body.

What Happens When Validation Fails?

If a client sends invalid data (e.g., an empty title), Spring Boot automatically intercepts the request, blocks execution, and throws a MethodArgumentNotValidException.

By default, Spring responds with an HTTP 400 Bad Request. You can customize the exact error message directly inside the annotation or via a messages.properties file:

@NotBlank(message = "Description cannot be blank")
Enter fullscreen mode Exit fullscreen mode

Conclusion & Feedback

Validating inputs right at the controller layer keeps your business logic clean and your database safe from corrupted data.

Thank you for reading this far! I wrote this article while learning Spring Boot, and I'd love to hear your thoughts, tips, or best practices in the comments below.

Happy coding! 🚀

Top comments (0)