Vaildation

Spring Boot / Validation

데이터 검증(Validation)

Bean Validation

💡 핵심 요약: 데이터 검증은 서버의 첫 번째 방어선입니다. 컨트롤러에서 일일이 if(data == null)을 작성하는 대신, 표준화된 Bean Validation을 통해 코드를 깔끔하게 관리할 수 있다.

1. if문 대신 애너테이션으로 자동화

과거에는 들어오는 데이터가 유효한지 확인하기 위해 서비스 로직 절반이 검증 코드였다.

하지만 스프링은 애너테이션 하나로 이 과정을 자동화해주는것이다 

자주 쓰는 검증 애너테이션

  • @NotBlank: null이 아니고, 최소 한 글자 이상의 공백이 아닌 문자가 포함되어야 함.
  • @Size(min=x, max=y): 문자열, 컬렉션 등의 크기를 제한함.
  • @Email: 이메일 형식인지 검증함.
  • @Positive / @Negative: 양수인지 음수인지 확인함.
애너테이션 의미 예시
@NotNull 값이 null이면 안 됨 필수 체크박스
@NotBlank 공백이나 빈 문자열 금지 이름, 아이디
@Min / @Max 최소/최대 숫자 제한 나이(0~150)
@Pattern 정규식을 이용한 정밀 검사 전화번호 형식

 

왜 필요 할까? 가장 큰 이유 3가지

 

1. 데이터 무결성 -> DB에 원하는 적합한 정보의 데이터만 가져올 수 있

2. 보안 -> 이상한 값을 넣어서 서버를 공격 하려는 시도를 1차적으로 차단  

3. 사용자 경험 -> 잘못된 입력이라고 친절하게 알려줘서 사용자가 수정을쉽게 하도록 도와줌  

2. 실전 적용: @Valid와 @RequestBody

DTO 객체 필드에 검증 규칙을 정의하고, 컨트롤러 파라미터 앞에 @Valid를 붙여주면 끝입니다.

// DTO에서 규칙 정의
public class JoinRequestDto {
    @NotBlank(message = "아이디는 필수입니다.")
    private String username;

    @Size(min = 8, message = "비밀번호는 최소 8자 이상이어야 합니다.")
    private String password;
}

// 컨트롤러에서 사용
@PostMapping("/join")
public String join(@Valid @RequestBody JoinRequestDto dto) {
    return "회원가입 성공";
}

3. 현업 개발자가 챙겨야 할 3가지 디테일

① Entity와 DTO의 분리

현업에서는 절대로 DB Entity 클래스에 직접 검증 애너테이션을 도배하지 않아야 한다. 

화면마다 요구되는 검증 규칙이 다르기 때문에(회원가입 vs 정보수정), 반드시 각 목적에 맞는 DTO를 만들고 그곳에서 검증을 수행합니다.

② @RestControllerAdvice를 통한 전역 예외 처리

검증에 실패하면 MethodArgumentNotValidException이 발생합니다. 이때 서버가 500 에러를 뱉게 두지 않고, 전역 예외 처리기에서 400(Bad Request) 응답과 함께 깔끔한 에러 메시지를 JSON으로 내려줘야 한다. 

③ 사용자 정의 애너테이션 (Custom Validator)

"전화번호 형식"이나 "특정 단어 포함 금지" 같은 복잡한 비즈니스 규칙은 직접 애너테이션을 만들어 관리합니다. 코드의 재사용성이 비약적으로 상승합니다.

4. 검증 방식 비교

방식 장점 단점
수동 검증 (if문) 직관적이고 자유로움 코드가 길어지고 가독성 최악
Bean Validation 가독성 우수, 표준화된 방식 복잡한 비즈니스 로직은 한계

정리 

Validation은 단순히 "데이터가 비었나?"를 체크 유효성 검사와 서버의 안정성과 아키텍처의 깔끔하게 해준다.

 

Q1. 데이터 검증(Validation)을 프론트엔드와 백엔드 중 어디서 하는 것이 맞을까요?

  • 답변: 둘 다 하는 것이 정답입니다.
    • 프론트엔드 검증: 사용자에게 즉각적인 피드백을 주어 사용자 경험(UX)을 향상시키고, 잘못된 요청이 서버로 가는 것을 1차적으로 차단해 서버 부하를 줄입니다.
    • 백엔드 검증: 프론트엔드 검증은 보안에 취약(Postman 등으로 우회 가능)하므로, 최종 방어선으로서 서버에서 반드시 한 번 더 검증해야 데이터 무결성을 보장할 수 있습니다.

Q2. @Valid와 @Validated의 차이점을 설명해 주세요.

  • 답변: | 구분 | @Valid | @Validated | 패키지 | jakarta.validation (자바 표준) | org.springframework (스프링 전용) | | 위치 | 컨트롤러의 메서드 파라미터 등 | 클래스 레벨 또는 메서드 파라미터 | | 특징 | 기본적인 객체 검증 수행 | 그룹 검증(Group Validation) 기능 제공 | | 사용처 | 일반적인 DTO 검증 | 특정 상황(회원가입/수정)마다 다른 검증이 필요할 때 |

Q3. Entity가 아닌 DTO에 검증 로직을 넣어야 하는 이유는 무엇인가요?

  • 답변: 계층 간의 역할 분리(Separation of Concerns) 때문입니다.
    • Entity는 DB와 매핑되는 핵심 도메인 모델이므로, 화면 종속적인 검증 로직이 섞이면 코드가 복잡해집니다.
    • 화면마다 요구하는 데이터 형식이 다를 수 있는데(예: 회원가입 시엔 비밀번호 필수, 정보 수정 시엔 선택), DTO를 사용하면 각 상황에 맞는 최적화된 검증을 독립적으로 수행할 수 있습니다.

Q4. 검증 에러 발생 시 스프링은 어떤 예외를 던지며, 어떻게 처리하나요?

  • 답변: @RequestBody를 사용하는 경우 MethodArgumentNotValidException이 발생합니다.
  • 현업에서는 이를 처리하기 위해 @RestControllerAdvice를 사용하여 전역적으로 예외를 가로챕니다. 이후 에러 메시지를 정제하여 클라이언트가 이해하기 쉬운 JSON 형태(예: ErrorResponse 객체)로 반환하는 방식을 주로 사용합니다.

Q5. 복잡한 비즈니스 규칙(예: DB 조회 후 중복 체크)도 Bean Validation 애너테이션으로 처리하나요?

  • 답변: 아니요, 보통은 Service 계층에서 처리합니다.
    • Bean Validation(@NotBlank 등)은 데이터의 형식(Format)을 검증하는 데 적합합니다.
    • DB를 조회하거나 외부 API와 통신해야 하는 비즈니스 정합성 검증은 Service 단에서 로직으로 처리하거나, 필요하다면 스프링의 Validator 인터페이스를 구현하여 별도로 분리합니다.

'Spring > spring 숙련' 카테고리의 다른 글

JPA Entity 연관 관계  (0) 2026.04.10
RestTemplate  (0) 2026.04.09
Session/Cookie/Filter/Listener  (0) 2026.04.09
쿠키(Cookie)와 세션(Session)  (1) 2026.04.09
인증(Authentication) vs 인가(Authorization)  (0) 2026.04.09