입력값 검증

커스텀 검증 어노테이션 사용 규칙 및 에러 응답 형식

마지막 수정: 2026-05

입력값 검증

기본 원칙

  • RqVo 작성 시 필드 위에 검증 어노테이션 작성
  • 검증 실패 시 표준 에러 응답 반환
  • 모든 외부 입력은 신뢰하지 않는다

검증 어노테이션 목록

어노테이션에러코드검증 내용
@RequiredField100null 또는 빈 문자열 체크
@MaxLength(n)101최대 길이 초과 체크
@ValidDateTime102날짜 형식 체크
@NumericOnly103숫자 형식 체크
@RequiredObject100중첩 객체 null 체크

검증 어노테이션 사용 예시

@Getter
@Setter
@ToString
public class UserVo extends GeneralVO {

    @RequiredField
    private String userId;          // 필수: null, 빈 문자열 불허

    @RequiredField
    @MaxLength(100)
    private String userNm;          // 필수, 최대 100자

    @RequiredField
    @MaxLength(200)
    private String userEmail;       // 필수, 최대 200자

    @MaxLength(20)
    @NumericOnly
    private String phoneNo;         // 숫자만 허용, 최대 20자

    @ValidDateTime
    private String birthDt;         // 날짜 형식 검증 (yyyyMMdd)

    @RequiredObject
    private AddressVo address;      // 중첩 객체 null 체크
}

검증 실패 에러 응답

검증 실패 시 아래 형식의 표준 에러 응답을 반환한다:

{
    "success": false,
    "errorCode": "100",
    "message": "userId: 필수 입력값입니다."
}

여러 필드 검증 실패:

{
    "success": false,
    "errorCode": "100",
    "message": "userId: 필수 입력값입니다., userNm: 필수 입력값입니다."
}

전역 검증 예외 처리

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler(ValidationException.class)
    public ResponseJson<Void> handleValidation(ValidationException e) {
        log.warn("입력값 검증 실패: {}", e.getMessage());
        return ResponseJson.fail(e.getErrorCode(), e.getMessage());
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseJson<Void> handleMethodArgumentNotValid(MethodArgumentNotValidException e) {
        String message = e.getBindingResult().getFieldErrors().stream()
                .map(fe -> fe.getField() + ": " + fe.getDefaultMessage())
                .collect(Collectors.joining(", "));
        return ResponseJson.fail("100", message);
    }
}

Service 레이어 비즈니스 검증

Bean Validation으로 처리할 수 없는 비즈니스 규칙은 Service에서 검증한다.

@Transactional(rollbackFor = Exception.class)
public void regist(UserVo vo) {
    // 비즈니스 규칙 검증
    if (userMapper.existsByUserId(vo.getUserId()) > 0) {
        throw new BusinessException("이미 사용 중인 아이디입니다.");
    }

    userMapper.regist(vo);
}

체크리스트

  • [ ] RqVo 필드에 검증 어노테이션 적용
  • [ ] @RequiredField: 필수 입력 필드
  • [ ] @MaxLength(n): 최대 길이 제한
  • [ ] @ValidDateTime: 날짜 형식 필드
  • [ ] @NumericOnly: 숫자만 허용 필드
  • [ ] @RequiredObject: 중첩 객체 null 체크
  • [ ] 검증 실패 시 표준 에러 응답 반환
  • [ ] 비즈니스 규칙 검증은 Service 레이어에서 처리