[Spring Boot] @Valid 검증이 동작하지 않는 경우
환경 : Spring Boot 3.x, Kotlin 1.9
에러 메시지
// @Valid를 붙였는데 유효하지 않은 값이 그대로 통과됨
// MethodArgumentNotValidException이 발생하지 않음
1. 원인
Spring Boot 3.x부터 spring-boot-starter-validation 의존성이 기본 포함 안 됨. 별도 추가 필요
또는 아래 케이스에서도 동작하지 않음
@Valid어노테이션 위치가 잘못된 경우- Kotlin
data class필드에 어노테이션이 안 먹는 경우 @Validated와@Valid혼동
2. 해결 방법
2.1) 의존성 추가
// build.gradle.kts
dependencies {
implementation("org.springframework.boot:spring-boot-starter-validation")
}
2.2) @Valid 위치 확인
Controller 메서드의 @RequestBody 앞에 @Valid 선언
// 동작 안 함
@PostMapping
fun save(@RequestBody request: MemberRequest) // @Valid 누락
// 정상
@PostMapping
fun save(@Valid @RequestBody request: MemberRequest)
2.3) Kotlin data class에서 field 타겟 지정
Kotlin은 생성자 파라미터와 필드가 분리되어 있어서 어노테이션이 필드에 안 붙을 수 있음. @field: 사용 타겟 지정 필요
// 동작 안 함
data class MemberRequest(
@NotBlank
val name: String,
@Email
val email: String
)
// 정상
data class MemberRequest(
@field:NotBlank
val name: String,
@field:Email
val email: String
)
※ Kotlin에서는 @field:를 안 붙이면 어노테이션이 생성자 파라미터에만 적용되고 필드에는 적용 안 됨
2.4) @Validated로 클래스 레벨 검증
@RequestParam이나 @PathVariable 검증은 @Valid가 아니라 클래스에 @Validated 필요
@Validated // 클래스 레벨에 선언
@RestController
class MemberController(private val memberService: MemberService) {
@GetMapping("/{id}")
fun getById(@PathVariable @Min(1) id: Long): Member {
return memberService.getById(id)
}
}
3. 에러 응답 커스터마이징
기본 응답은 가독성이 떨어짐. @ExceptionHandler로 포맷 정리
@RestControllerAdvice
class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException::class)
fun handleValidation(e: MethodArgumentNotValidException): ResponseEntity<Map<String, String>> {
val errors = e.bindingResult.fieldErrors.associate {
it.field to (it.defaultMessage ?: "")
}
return ResponseEntity.badRequest().body(errors)
}
}
응답 예시
{
"name": "must not be blank",
"email": "must be a well-formed email address"
}
'Kotlin' 카테고리의 다른 글
| Kotlin + Spring Boot 시작하기 (0) | 2026.03.10 |
|---|