Bean Validation 표준을 통해 이를 선언적으로 처리할 수 있게 돕습니다.build.gradle)spring-boot-starter-web에 기본적으로 포함되어 있어, 별도의 의존성을 추가할 필요가 없는 경우가 많습니다. 만약 없다면 추가합니다.implementation 'org.springframework.boot:spring-boot-starter-validation'| 어노테이션 | 설명 |
|---|---|
@NotBlank | null이 아니고, 최소한 하나의 비공백 문자를 포함해야 함. (문자열 전용) |
@NotNull | null이 아니어야 함. (모든 타입) |
@NotEmpty | null이 아니고, 비어있지 않아야 함. (문자열, 컬렉션, 맵) |
@Size(min=, max=) | 문자열, 컬렉션 등의 크기가 지정된 범위 내에 있어야 함. |
@Email | 유효한 이메일 형식이어야 함. |
@Min(value) / @Max(value) | 지정된 숫자 값 이상/이하이어야 함. |
@Pattern(regexp=) | 지정된 정규 표현식과 일치해야 함. |
@Valid 어노테이션을 컨트롤러 메서드의 파라미터(주로 @RequestBody가 붙은 DTO) 앞에 붙이면, Spring이 해당 DTO에 정의된 검증 규칙을 자동으로 검사합니다.
만약 검증에 실패하면, MethodArgumentNotValidException이라는 예외가 발생합니다.
// PostCreateRequest.java
@Getter
@NoArgsConstructor
public class PostCreateRequest {
@NotBlank(message = "제목은 필수 입력 값입니다.")
@Size(max = 100, message = "제목은 100자 이내로 입력해주세요.")
private String title;
@NotEmpty(message = "내용은 비어있을 수 없습니다.")
private String content;
}
// PostController.java
@PostMapping
public ResponseEntity<Void> createPost(@Valid @RequestBody PostCreateRequest request) {
// @Valid: DTO의 검증 어노테이션을 기반으로 유효성 검사를 수행
Long postId = postService.createPost(request);
return ResponseEntity.created(URI.create("/api/posts/" + postId)).build();
}
@RestControllerAdvice (또는 @ControllerAdvice)@RestController에서 발생하는 예외를 가로채서 처리하는 클래스를 선언합니다.@ExceptionHandler: 특정 예외 타입을 지정하여, 해당 예외가 발생했을 때 실행될 메서드를 정의합니다.// ErrorCode.java (Enum)
@Getter
@RequiredArgsConstructor
public enum ErrorCode {
POST_NOT_FOUND(HttpStatus.NOT_FOUND, "게시글을 찾을 수 없습니다."),
INVALID_INPUT(HttpStatus.BAD_REQUEST, "입력값이 올바르지 않습니다.");
private final HttpStatus status;
private final String message;
}
// BusinessException.java
@Getter
public class BusinessException extends RuntimeException {
private final ErrorCode errorCode;
public BusinessException(ErrorCode errorCode) {
super(errorCode.getMessage());
this.errorCode = errorCode;
}
}
// ErrorResponse.java (에러 응답 DTO)
@Getter
@AllArgsConstructor
public class ErrorResponse {
private int status;
private String message;
}
// GlobalExceptionHandler.java
@RestControllerAdvice
public class GlobalExceptionHandler {
// 우리가 직접 정의한 비즈니스 예외 처리
@ExceptionHandler(BusinessException.class)
public ResponseEntity<ErrorResponse> handleBusinessException(BusinessException e) {
ErrorCode errorCode = e.getErrorCode();
return ResponseEntity
.status(errorCode.getStatus())
.body(new ErrorResponse(errorCode.getStatus().value(), errorCode.getMessage()));
}
// @Valid 검증 실패 예외 처리
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleValidationException(MethodArgumentNotValidException e) {
// 여러 검증 오류 중 첫 번째 오류 메시지를 사용
String errorMessage = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(new ErrorResponse(HttpStatus.BAD_REQUEST.value(), errorMessage));
}
// 그 외 예상치 못한 모든 서버 예외 처리
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleException(Exception e) {
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(), "서버 내부 오류가 발생했습니다."));
}
}
spring-boot-starter-validation과 @Valid 어노테이션을 통해, DTO에 선언된 검증 규칙을 컨트롤러에서 자동으로 검사하여 데이터의 무결성을 보장할 수 있습니다.@RestControllerAdvice와 @ExceptionHandler를 사용하면, 애플리케이션 전역에서 발생하는 예외를 중앙에서 일관되게 처리할 수 있습니다.