728x90
반응형

[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"
}

 

728x90
반응형

'Kotlin' 카테고리의 다른 글

Kotlin + Spring Boot 시작하기  (0) 2026.03.10

+ Recent posts