1. 벨리데이션이란?
입력된 데이터가 올바른 값인지 검증하는 과정
여기서 올바른 값이 의미하는것은?
1. 형식이 올바른지
예) 회원가입 시 아이디를 이메일로 사용할 경우, 입력된 값이 이메일 형식(user@example.com)을 충족해야 한다.
일반적으로 이러한 형식 검증은 Entity, DTO에서 수행한다.
2. 비즈니스 규칙에 맞는지
예) 회원가입 시, 입력된 이메일이 이미 존재하는 경우 중복 가입을 방지해야 한다.
이는 "이메일은 유니크해야 한다"는 비즈니스 규칙을 검증하는 과정이다. 일반적으로 이러한 비즈니스 규칙에 맞는지 검증하는 과정은 서비스 로직에 포함된다.
// 회원 중복 확인
Optional<User> checkUsername = userRepository.findByUsername(username);
if (checkUsername.isPresent()) {
throw new IllegalArgumentException("중복된 사용자가 존재합니다.");
}
2. 사용방법
Entity 와 DTO에 벨리데이션을 추가하려면 build.gradle에 의존성과 controller에 @Valid 어노테이션을 추가해야 한다.
// validation
implementation 'org.springframework.boot:spring-boot-starter-validation'
DTO에서 벨리데이션 처리를 원한다면 @Valid 어노테이션을 컨트롤러 파라미터의 @RequestBody 어노테이션과 붙여 입력해야 한다.
// 회원가입
@PostMapping("/sign-up")
public ResponseEntity<?> signUp(@Valid @RequestBody SignUpReq req) {
authService.signUp(req);
return ResponseEntity.ok().build();
}
컨트롤러에 @Valid 어노테이션을 적용했다면 DTO에서 벨리데이션 관련 어노테이션들을 사용할 수 있다.
@NotNull : null 불가 ("" 빈 문자열 허용)
@NotEmpty : null, "" 불가 / " " 공백 문자열 가능
@NotBlank : null, "", " " 과 같은 공백 모두 불가
@Size(min=, max=) : 문자열 또는 컬렉션의 최소/최대 길이 제한
@Pattern(regexp=) : 정규식 패턴과 일치하는지 검사
@Email : 이메일 형식인지 검증
이 외에도 다양한 어노테이션들이 있다.
@Data
public class SignUpReq {
@NotBlank(message = "사용자 이름(username)은 필수 입력값입니다.")
@Size(min = 4, max = 10, message = "사용자 이름(username)은 4자리 이상 10자리 이하로 입력해야 합니다.")
@Pattern(regexp = "^[a-zA-Z0-9]+$", message = "사용자 이름(username)은 영어와 숫자만 입력 가능합니다.")
private String username;
@NotBlank(message = "비밀번호(password)는 필수 입력값입니다.")
@Size(min = 4, max = 10, message = "비밀번호(password)는 4자리 이상 10자리 이하로 입력해야 합니다.")
@Pattern(regexp = "^[a-zA-Z0-9]+$", message = "비밀번호(password)는 영어와 숫자만 입력 가능합니다.")
private String password;
private UserRoleEnum role;
private String adminToken;
}
3. 결과
테스트를 위해 일부러 벨리데이션에 맞지 않는 요청을 아래와 같이 보내면
POST
http://localhost:8080/api/v1/auth/sign-up
{
"username" : "tes",
"password" : "1234",
"role" : "ADMIN",
"adminToken" : "adminToken"
}
Spring Security에 의해 MethodArgumentNotValidException 예외가 발생한다.
2025-03-03T16:43:27.403+09:00 WARN 7348 --- [springboot3template] [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity<?> com.example.springboot3template.auth.presentation.controller.AuthController.signUp(com.example.springboot3template.auth.application.dto.req.SignUpReq): [Field error in object 'signUpReq' on field 'username': rejected value [tes]; codes [Size.signUpReq.username,Size.username,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [signUpReq.username,username]; arguments []; default message [username],10,4]; default message [사용자 이름(username)은 4자리 이상 10자리 이하로 입력해야 합니다.]] ]
이때 벨리데이션의 경우 잘못된 요청을 보낸 Bad Request 로 status가 400이 반환 되어야 하지만 기본적으로 Spring Security에서는 MethodArgumentNotValidException 예외시 status 403을 반환하도록 되어 있다. 이를 해결하기 위해서는 추가로 전역예외처리 등을 통해 적절한 status를 반환하도록 설정해야 한다.
'Spring Boot > Sprng Boot Sample Code' 카테고리의 다른 글
[Spring Boot 3.x] accessToken & refreshToken with Redis (0) | 2025.03.28 |
---|---|
[Spring Boot 3.x] 6. @ControllerAdvice를 활용한 Global Exception Handling 전역 예외 처리 (0) | 2025.03.03 |
Spring Boot 에서 네이버 클라우드 Object Storage 에 파일 업로드 (1) | 2025.03.03 |
[SpringBoot 3.x] 4. @PreAuthorize 어노테이션을 이용한 API 인가 설정 (0) | 2025.03.03 |
[Spring Boot 3.x] 3. JWT 토큰 인증(filter) & API 테스트 (0) | 2025.03.01 |