본문으로 건너뛰기

값이 반드시 유효해야 할 때: Spring Boot에서 Validation 처리하기

2025년 11월 4일에 작성되었고, 블로그를 이전하며 옮겨온 포스트입니다.
여기에서 원본을 확인할 수 있습니다.

왜 Validation을 추가해야 했을까?

현재 개발 중인 앱에 피드백 기능이 있는데, 프론트엔드에서는 300자로 글자 수 제한을 두고 있지만, API를 이용해 직접 요청을 보내면, 글자 수 제한 없이 요청이 가능한 것을 확인했다. 이는 앱을 사용하는 사용자가 비정상적으로 요청을 보내게 되면 백엔드에서는 무한정으로 보낼 수 있기 때문에 혹시나 하는 상황을 대비해 백엔드에서도 이를 처리할 수단이 필요하다 생각되었다. 프론트엔드에서만 글자 수 제한을 둬서 막아도, 백엔드에서는 무한정 받을 수 있기 때문이다.

Spring Boot Validation 설정하기

Spring Boot Validation 을 사용하려면, build.gradle에서 아래의 의존성을 추가해줘야 한다.

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-validation'
}

적용하기

@RequestBody 를 사용하는 부분 앞에 @Valid 어노테이션을 추가해준다

@PostMapping("/request")
public ResponseEntity<SupportResponseDto> requestSupport(@Valid @RequestBody SupportRequestDto supportRequestDto) {
    return supportService.requestSupport(SecurityUtil.getCurrentUsername(), supportRequestDto);
}

그 다음, 위 Controller에서 이용하는 SupportRequestDto에 대한 부분을 구현했다. 아래와 같이 Validation 값을 추가했다.

  • supportType은 Null이 되어서는 안 된다.
  • title은 최소 5자, 최대 20자까지만 허용한다.
  • content는 최소 20자, 최대 300자까지만 허용한다.
public class SupportRequestDto {
    @NotNull
    private SupportType supportType;

    @Size(min = 5, max = 20)
    private String title;

    @Size(min = 20, max = 300)
    private String content;
}

테스트하기

Validation을 적용하기 이전

Validation을 적용하기 이전에는 아래의 요청 값이 200 OK로 정상 처리되었다. 아래 값을 확인해 보면, title의 값은 20자가 초과되었고, content 값 또한 300자가 초과된 상황이다.

{
  "supportType": "APP",
  "title": "대충 이 곳이 Input 이 문장dasd",
  "content": "대충 이 곳이 Input 이 문장은 300자 정도로 작성될 예정이에요. 대충 이 곳이 Input 이 문장은 300자 정도로 작성될 예정이에요. 대충 이 곳이 Input 이 문장은 300자 정도로 작성될 예정이에요. 대충 이 곳이 Input 이 문장은 300자 정도로 작성될 예정이에요. 대충 이 곳이 Input 이 문장은 300자 정도로 작성될 예정이에요. 대충 이 곳이 Input 이 문장은 300자 정도로 작성될 예정이에요. 대충 이 곳이 Input 이 문장은 300자 정도로 작성될 예정이에요. 대충 이 곳이 Input 이 문장은 300자 정도로 작성될 예정이에요."
}

하지만 위와 같이 API(백엔드)에서는 정상 처리되어 Support가 등록된 것을 확인할 수 있다.

Validation을 적용한 이후

위와 같이 똑같은 요청 값으로 API 요청을 보낸 것을 위 사진을 통해 확인할 수 있다.

하지만, 400 Bad Request 결과가 나오며 등록이 되지 않는 것을 확인할 수 있다. 이제 아래와 같이 정상적인 값(Validation을 만족하는 요청)으로 요청을 다시 보내보면

{
  "supportType": "APP",
  "title": "대충 이 곳이",
  "content": "대충 이 곳이 Input 이 문장은 300자 정도로 작성될 예정"
}

200 OK 결과 값이 나오며, 정상적으로 등록되는 걸 확인하며 Validation이 잘 적용된 것을 확인할 수 있어요.

여러가지 Validation

  • @Email
    • 이메일 형식(abc@abc.com)의 유효성을 검증해요.
    • 문자열의 값만 지원해요.
  • @Future
    • 현재보다 이후의 날짜, 시간인지 검증해요.
    • Date, LocalDateTime 등의 타입만 지원해요.
    • 주로 생년월일 검증에 사용해요.
  • @Past
    • 현재보다 과거의 날짜, 시간인지 검증해요.
    • @Future 어노테이션과 반대돼요.
    • Date, LocalDateTime 등의 타입만 지원해요.
    • 주로 생년월일 검증에 사용해요.
  • @Max(value = 값)
    • value의 값보다 큰 값만 유효해요.
    • 주로 나이나, 최대 값이 정해져 있을 때 사용해요.
  • @Min(value = 값)
    • value의 값보다 작은 값만 유효해요.
    • 주로 나이나, 최소 값이 정해져 있을 때 사용해요.
  • @NotNull
    • Null의 값은 유효하지 않아요.
  • @NotEmpty
    • Null 또는 값이 비어있으면 유효하지 않아요.
  • @Pattern(regxp = 정규식)
    • 값이 정규식에 해당(일치)하는지 검증해요.
    • 주로 유효한 URL을 가려낼 때 사용해요.
  • @Size(min = 최소값, max = 최대값)
    • 값의 길이가 최소 값보다 커야하고, 최대 값보다 작아야 유효해요.
    • 주로 문자열의 길이의 제한을 둘 때 사용해요.