0Pricing
Spring Boot 4 Microservices & REST APIs · Урок

Проверка запросов и ответов

Реализуйте проверку данных во входящих запросах и формируйте единообразные ответы с ошибками.

«Проверка запросов и ответов» — бесплатный урок Spring Boot 4 Microservices & REST APIs на CoddyKit. Это урок 1 из 3. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Spring Boot 4 Microservices & REST APIs, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Spring Boot 4 Microservices & REST APIs содержит 3 уроков всего.

Части этого урока еще не переведены и отображаются на английском.

Why Validate Requests?

When building REST APIs, clients send data to your server. This data often needs to meet certain rules, like a field not being empty, or a number being within a specific range.

  • Data Integrity: Ensures your database stores only valid information.
  • Security: Prevents malicious or malformed data from causing issues.
  • User Experience: Provides clear, immediate feedback to clients when their input is incorrect.

Validation is crucial for robust and reliable APIs.

Spring's Validation Tools

Spring Boot makes data validation easy by integrating with the Jakarta Bean Validation API (JSR 380). You'll primarily use the @Valid annotation in your controller methods.

Common validation annotations include:

  • @NotNull: Field must not be null.
  • @NotBlank: String must not be null and must contain at least one non-whitespace character.
  • @Size(min=X, max=Y): String or collection size must be within range.
  • @Min(X), @Max(Y): Numeric value must be within range.
  • @Email: String must be a valid email format.

Data Transfer Objects (DTOs)

For incoming request bodies, it's best practice to use a Data Transfer Object (DTO). A DTO is a simple Java class that mirrors the structure of the data you expect from the client.

You apply validation annotations directly to the fields within your DTO. This keeps your controller clean and separates validation logic from business logic.

Implementing Basic Validation

Let's create a ProductRequest DTO with some validation rules and use it in a Spring Boot controller. The @Valid annotation triggers the validation.

Try sending a request with an empty name or a price less than 1.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Min;

// DTO for product creation request
class ProductRequest {
    @NotBlank
    private String name;
    @Min(1)
    private double price;

    // Getters and Setters
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public double getPrice() { return price; }
    public void setPrice(double price) { this.price = price; }
}

@RestController
@RequestMapping("/api/products")
class ProductController {

    @PostMapping
    public String createProduct(@Valid @RequestBody ProductRequest productRequest) {
        // If validation passes, process the product request
        return "Product '" + productRequest.getName() + 
               "' with price " + productRequest.getPrice() + 
               " created successfully!";
    }
}

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}

Customizing Error Messages

The default validation error messages can sometimes be generic. You can provide your own custom messages for each annotation to make them more user-friendly and specific to your application.

Just add the message attribute to the validation annotation, like this: @NotBlank(message="Product name is required").

Custom Message Example

Let's update our ProductRequest DTO to include custom error messages. This helps clients understand exactly what went wrong with their input.

Run this and try the previous invalid inputs again. You should see your custom messages.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Min;

// DTO for product creation request with custom messages
class ProductRequest {
    @NotBlank(message = "Product name cannot be empty")
    private String name;
    @Min(value = 1, message = "Product price must be at least 1")
    private double price;

    // Getters and Setters
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public double getPrice() { return price; }
    public void setPrice(double price) { this.price = price; }
}

@RestController
@RequestMapping("/api/products")
class ProductController {

    @PostMapping
    public String createProduct(@Valid @RequestBody ProductRequest productRequest) {
        return "Product '" + productRequest.getName() + 
               "' with price " + productRequest.getPrice() + 
               " created successfully!";
    }
}

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}

Handling Validation Exceptions

When validation fails, Spring automatically throws a MethodArgumentNotValidException. By default, Spring handles this by returning an HTTP 400 Bad Request status with a simple error body.

However, for a consistent API, you'll want to customize this error response. This means catching the exception and formatting the response in a structured way, often with specific error codes or details.

Global Error Handler

To provide a uniform error response across your entire API, you can use a Global Error Handler. This is typically a class annotated with @ControllerAdvice.

Inside this class, you define methods annotated with @ExceptionHandler to catch specific exception types, like MethodArgumentNotValidException, and return a custom ResponseEntity.

Error Handling in Action

Here's how to create a global error handler that catches validation exceptions and returns a structured JSON error response. This improves API consistency and makes error handling easier for clients.

Run this code and try sending an invalid product request. Observe the structured error response.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Min;
import org.springframework.validation.FieldError;

import java.util.HashMap;
import java.util.Map;

// DTO for product creation request
class ProductRequest {
    @NotBlank(message = "Product name cannot be empty")
    private String name;
    @Min(value = 1, message = "Product price must be at least 1")
    private double price;

    // Getters and Setters
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public double getPrice() { return price; }
    public void setPrice(double price) { this.price = price; }
}

// Custom Error Response DTO
class ErrorResponse {
    private int status;
    private String message;
    private Map<String, String> errors;

    public ErrorResponse(int status, String message, Map<String, String> errors) {
        this.status = status;
        this.message = message;
        this.errors = errors;
    }

    // Getters
    public int getStatus() { return status; }
    public String getMessage() { return message; }
    public Map<String, String> getErrors() { return errors; }
}

@RestController
@RequestMapping("/api/products")
class ProductController {

    @PostMapping
    public String createProduct(@Valid @RequestBody ProductRequest productRequest) {
        return "Product '" + productRequest.getName() + 
               "' with price " + productRequest.getPrice() + 
               " created successfully!";
    }
}

@ControllerAdvice
class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<ErrorResponse> handleValidationExceptions(
            MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getAllErrors().forEach((error) -> {
            String fieldName = ((FieldError) error).getField();
            String errorMessage = error.getDefaultMessage();
            errors.put(fieldName, errorMessage);
        });
        ErrorResponse errorResponse = new ErrorResponse(
            HttpStatus.BAD_REQUEST.value(), 
            "Validation failed", 
            errors
        );
        return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
    }
}

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}

Validation Quick Check

Consider a DTO field: @Size(min = 5, max = 10, message = "Length must be between 5 and 10") String code;

Which input for code would cause a validation error?

Recap: Validation & Errors

In this lesson, you learned how to implement robust request validation in Spring Boot and provide consistent error responses.

  • We used @Valid and standard bean validation annotations like @NotBlank and @Min with DTOs.
  • You saw how to customize validation error messages.
  • We implemented a @ControllerAdvice global error handler to catch MethodArgumentNotValidException and return structured, user-friendly error responses.

Well done! Consistent validation and error handling are key for a professional API.

Часто задаваемые вопросы

Урок «Проверка запросов и ответов» бесплатный?

Да — полный текст урока «Проверка запросов и ответов» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Spring Boot 4 Microservices & REST APIs, подпишись на CoddyKit PRO. Курс Spring Boot 4 Microservices & REST APIs содержит 3 уроков всего.

Чему я научусь в уроке «Проверка запросов и ответов»?

Реализуйте проверку данных во входящих запросах и формируйте единообразные ответы с ошибками. Ты практикуешь Spring Boot 4 Microservices & REST APIs с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Spring Boot 4 Microservices & REST APIs?

Предыдущий опыт не требуется. Spring Boot 4 Microservices & REST APIs на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 3.

Сколько времени занимает урок «Проверка запросов и ответов»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Spring Boot 4 Microservices & REST APIs?

Да. Каждый урок Spring Boot 4 Microservices & REST APIs включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Проверка запросов и ответов
  2. Постраничный вывод и сортировка
  3. Принципы HATEOAS для REST
← Назад к Spring Boot 4 Microservices & REST APIs