입력값 검증
기본 원칙
- RqVo 작성 시 필드 위에 검증 어노테이션 작성
- 검증 실패 시 표준 에러 응답 반환
- 모든 외부 입력은 신뢰하지 않는다
검증 어노테이션 목록
| 어노테이션 | 에러코드 | 검증 내용 |
|---|---|---|
@RequiredField | 100 | null 또는 빈 문자열 체크 |
@MaxLength(n) | 101 | 최대 길이 초과 체크 |
@ValidDateTime | 102 | 날짜 형식 체크 |
@NumericOnly | 103 | 숫자 형식 체크 |
@RequiredObject | 100 | 중첩 객체 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 레이어에서 처리