요청 및 응답 검증
들어오는 요청의 데이터를 검증하고 일관된 오류 응답 형식을 구현합니다.
요청 및 응답 검증은(는) CoddyKit의 무료 Spring Boot 4 Microservices & REST APIs 강의입니다. 이것은 3개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 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
@Validand standard bean validation annotations like@NotBlankand@Minwith DTOs. - You saw how to customize validation error messages.
- We implemented a
@ControllerAdviceglobal error handler to catchMethodArgumentNotValidExceptionand return structured, user-friendly error responses.
Well done! Consistent validation and error handling are key for a professional API.
자주 묻는 질문
“요청 및 응답 검증” 강의는 무료인가요?
네 — “요청 및 응답 검증” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Spring Boot 4 Microservices & REST APIs 강의 전체를 잠금 해제할 수 있습니다. Spring Boot 4 Microservices & REST APIs 강의에는 총 3개의 강의가 포함되어 있습니다.
“요청 및 응답 검증”에서 뭘 배우나요?
들어오는 요청의 데이터를 검증하고 일관된 오류 응답 형식을 구현합니다. 브라우저에서 직접 실행하는 실습 코드로 Spring Boot 4 Microservices & REST APIs을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Spring Boot 4 Microservices & REST APIs을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Spring Boot 4 Microservices & REST APIs은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 3개 중 1번째 강의입니다.
“요청 및 응답 검증” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Spring Boot 4 Microservices & REST APIs 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Spring Boot 4 Microservices & REST APIs 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 요청 및 응답 검증
- 페이지 매김 및 정렬
- REST를 위한 HATEOAS 원칙