[Spring Boot 3.x] 5. @Valid 어노테이션을 통한 DTO validation 설정

2025. 3. 3. 17:01·Spring Boot/Sprng Boot Sample Code

 

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
'Spring Boot/Sprng Boot Sample Code' 카테고리의 다른 글
  • [Spring Boot 3.x] accessToken & refreshToken with Redis
  • [Spring Boot 3.x] 6. @ControllerAdvice를 활용한 Global Exception Handling 전역 예외 처리
  • Spring Boot 에서 네이버 클라우드 Object Storage 에 파일 업로드
  • [SpringBoot 3.x] 4. @PreAuthorize 어노테이션을 이용한 API 인가 설정
Yun-seul
Yun-seul
재능이 없으면 열심히라도 하자
  • Yun-seul
    윤슬
    Yun-seul
  • 전체
    오늘
    어제
    • 분류 전체보기 (22)
      • Java (1)
        • Java 기본 (1)
      • Spring Boot (9)
        • Sprng Boot Sample Code (9)
      • Docker (1)
      • Kubernetes (7)
        • Common (3)
        • GKE(Google Kubernetes Engin.. (4)
        • EKS(Elastic Kubernetes Serv.. (0)
      • Redis (0)
      • AWS (0)
      • Git (0)
      • Reflection (1)
      • Troubleshooting (3)
      • Performance Tuning (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    임시디렉토리
    전역예외처리
    재요청
    globalexception
    docker
    SpringBoot
    unable to create tempdir. java.io.tmpdir is set to
    에러코드관리
    GKE
    onceperrequestfilter
    rfc6750
    kubernetes
    필터2번
    커스텀익셉션
    어세스토큰
    jwt토큰 #로그인 #회원가입 #쿠키 #보안설정
    @value #null #어노테이션 #springboot #springioc #컨테이너
    djava.io.tmpdir
    methodargumentnotvalidexception
    쿠버네티스
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Yun-seul
[Spring Boot 3.x] 5. @Valid 어노테이션을 통한 DTO validation 설정
상단으로

티스토리툴바