[Spring Boot] 스프링 유효성 검사 Validation (@Valid, @Validated, Bean Validation)

2024. 8. 13. 22:59· Spring Boot
목차
  1. 1. 유효성 검사
  2. 2. Spring Validation
  3. 3. Bean Validation
  4. 3-1. 유효성 검사 어노테이션 정리
  5. 3-2. 예제 코드
  6. 4. 통합 예제 (@Valid 사용)
  7. 4-1. build.gradle에 라이브러리 추가
  8. 4-2. UserDto
  9. 4-3. 컨트롤러
  10. 4-4. 실행 결과
  11. 5. 에러 메시지 설정 방법

1. 유효성 검사

  • 사용자에게 입력받은 데이터가 기준에 부합한지 검사하는 과정임
  • 오류나 보안 문제 예방 가능

⇒ 데이터 무결성 보장, 시스템 안정성 확보, 보안 유지 가능!

  • 스프링에서 주된 유효성 검사 방법
    • Spring Validation + Bean Validation
      • Spring Validation : 유효성 검사 기능 (Bean Validation을 기반으로 작동)
      • Bean Validation : 유효성 검사 API

 

2. Spring Validation

  • 스프링 프레임워크에서 제공하는 유효성 검사 기능
  • Java Bean Validation API를 기반으로 유효성 검사!
  • 스프링 MVC와 통합되어 사용
  • @Valid, @Validated 사용
    • @Valid
      • 자바에서 지원 (JSR-303 자바 표준)
      • 메서드 인자 또는 클래스에 적용 ⇒ 해당 객체의 유효성 검사
      • 스프링 MVC에서 컨트롤러에서 DTO의 유효성 검사 시 주로 사용
      @PostMapping("/user")
      public ResponseEntity<String> createUser(@RequestBody @Valid UserDto userDto) {
          // 유효성이 검사된 userDto 사용
          return ResponseEntity.ok("사용자가 생성되었습니다.");
      }
    • @Validated
      • 스프링에서 지원
      • @Valid 어노테이션의 기능 포함
      • 클래스 레벨에서 사용됨
      • 그룹화된 유효성 검사 지원!
      @PostMapping("/user")
      public ResponseEntity<String> createUser(@RequestBody @Validated(UserCreationGroup.class) UserDto userDto) {
          // UserCreationGroup에 해당하는 유효성 검사가 수행된 userDto 사용
          return ResponseEntity.ok("사용자가 생성되었습니다.");
      }
      
      @PostMapping("/user/v2")
      public ResponseEntity<String> createUserV2(@RequestBody @Validated({UserCreationGroup1.class, UserCreationGroup2.class} UserDto userDto) {
          // 2개의 그룹에 해당하는 유효성 검사가 수행된 userDto 사용
          return ResponseEntity.ok("사용자가 생성되었습니다. (v2)");
      }
  • 커스텀 유효성 검사 로직 구현 가능한 Validator 인터페이스도 제공
    ⇒ Spring Validation의 기본 기능 외의 사용자 정의 검증 로직 추가 가능!
    • Validator 인터페이스 구현 예제 코드

 

1. 사용자 정의 Validator 클래스 (구현체)

public class UserValidator implements Validator {
		
    @Override
    public boolean supports(Class<?> clazz) {
        return UserDto.class.equalss(clazz);
    }
		
    @Override
    public void validate(Object target, Errors errors) {
        UserDto user = (UserDto) target;
				
        // name -> 유효성 검사
        if(StringUtils.isBlank(user.getName()) {
            errors.rejectValue("name", "name.blank", "이름은 필수로 입력해야 합니다!");
        }
				
        // email -> 유효성 검사
        if(user.getEmail() == null || user.getEmail.matches("^[A-Za-z0-9+_.-]+@(.+)$")) {
            errors.rejectValue("email", "email.inValid", "유효한 이메일 주소가 아닙니다!");
        }
			
        if(user.getPassword() == null || user.getPassword.length() < 8) {
            errors.rejectValue("password", "password.invalid", "유효한 비밀번호가 아닙니다!");
        }
				
    }
}
  • Supports(Class<?> clazz)
    • 주어진 클래스 검사 가능 여부 반환
  • validate(Object target, Errors errors)
    • target 객체에 대한 유효성 검사 진행
    • 오류는 Errors 객체에 추가함
    • rejectValue(필드명, 오류코드, 오류메시지에 포함될 인자(배열 형태), 기본 오류메시지)
      • 스프링의 Errors 인터페이스에서 제공하는 메서드
      • 특정 필드의 유효성 검사 실패 시 해당 필드에 대한 오류 등록하는 기능

2. 컨트롤러

@RestController
public class UserController {

    private final UserValidator userValidator;
		
    // 사용자 정의 Validator 의존 주입
    @Autowired
    public UserController(UserValidator userValidator) {
        this.userValidator = userValidator;
    }
		
    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.addValidators(productValidator);
    }
		
	@PostMapping("/user/register")
	public String register(@RequestBody UserDto userDto, BindingResult bindingResult) {
				
        userValidator.validate(userDto, result);  // 유효성 검사 수행!!
			
        if(result.hasErrors) {
            StringBuilder errors = new StringBuilder("에러 발생 : ");
            result.getFieldErrors().forEach(error -> {
                errors.append(error.getDefaultMessage()).append("; ");
            });
            return errors.toString();
        }
				
        return "유저 등록 성공";
    }
}
  • @InitBinder
    • WebDataBinder에 사용자 정의 Validator 클래스를 등록함
  • BindingResult
    • 유효성 검사를 수행하고 발생한 오류들은 BindingResult 객체에 담김

 

3. Bean Validation

  • Java EE (Enterprise Edition) 에서 제공하는 표준 유효성 검사 API
  • 어노테이션 기반으로 객체의 속성이 유효한지를 검증함
  • Hibernate Validator 가 Bean Validation 의 구현체로 가장 많이 사용됨
  • 어노테이션 (대표적 : @NotNull, @Min 등) 을 클래스(DTO) 의 필드에 직접 적용

 

3-1. 유효성 검사 어노테이션 정리

Hibernate Validator 8.0.1.Final - Jakarta Bean Validation Reference Implementation: Reference Guide

3-1-1. 문자열

  • @Null : null 값만 허용
  • @NotNull : null 값 허용 x
  • @NotEmpty : 공백 허용 x, “ “는 허용
  • @NotBlank : 공백, “ “ 모두 허용 x

3-1-2. 최대, 최소 → BigDecimal, BigInteger, int, long 등의 타입 지원

  • @Min(value = 최솟값) : 최솟값 이상의 값만 허용
  • @Max(value = 최댓값) : 최댓값 이하의 값만 허용

3-1-3. 값 범위

  • @Positive : 양수만 허용
  • @PositiveOrZero : 양수와 0 만 허용
  • @Negative : 음수만 허용
  • @NegativeOrZero : 음수와 0 만 허용

3-1-4. 시간 → Date, LocalDate, LocalDateTime 등의 타입 지원

  • @Future : 현재보다 미래만 허용
  • @FutureOrPresent : 현재와 미래만 허용
  • @Past : 현재보다 과거만 허용
  • @PastOrPresent : 현재와 과거만 허용

3-1-5. 이메일

  • @Email : 이메일 형식만 허용 (공백 허용)

3-1-6. true, false

  • @AssertTrue : true만 허용, null 체크 x
  • @AssertFalse : false만 허용, null 체크 x

3-1-7. 길이 (문자열, 배열, 컬렉션의 길이나 크기)

  • @Size(min = 최솟값, max = 최댓값) : 최솟값 이상 최댓값 이하의 범위만 허용

3-1-8. 정규식

  • @Pattern(regexp = 정규식) : 정규식 검사

 

3-2. 예제 코드

@Getter @Setter
public class UserDto {
		
    @NotBlank(message = "이름은 필수로 입력해야 합니다")
    private String name;
		
    @Email(message = "이메일 주소가 유효하지 않습니다")
    @NotBlank(message = "이메일은 필수로 입력해야 합니다")
    private String email;
		
    @Size(min = 6, max = 12, message = "아이디는 6~12자리여야 합니다")
    private String id;
		
    @Size(min=8, message = "비밀번호는 8자리 이상이어야 합니다")
    private String password;
		
}
  • message = 메시지
    • 에러 메시지 설정 가능

 

4. 통합 예제 (@Valid 사용)

  • Spring Validation : Bean Validation API 활용하여 유효성 검사를 수행하는 스프링의 기능임
  • 즉, 스프링은 Bean Validation의 규칙 사용하여 유효성 검증함

⇒ 보통 Bean Validation + Spring Validation으로 유효성 검증 (validation) 함 !

 

4-1. build.gradle에 라이브러리 추가

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-validation'
}
  • 해당 라이브러리에 Hibernate Validator 포함됨 → Bean Validation API 사용 가능함!

 

4-2. UserDto

@Getter @Setter
public class UserDto {
		
    @NotBlank(message = "이름은 필수로 입력해야 합니다")
    private String name;
		
    @Email(message = "이메일 주소가 유효하지 않습니다")
    @NotBlank(message = "이메일은 필수로 입력해야 합니다")
    private String email;
		
    @Size(min = 6, max = 12, message = "아이디는 6~12자리여야 합니다")
    private String id;
		
    @Size(min=8, message = "비밀번호는 8자리 이상이어야 합니다")
    private String password;
		
}

 

 

4-3. 컨트롤러

@RestController
@RequestMapping("/api/users")
@Validated
public class UserController {

    @PostMapping
    public ResponseEntity<String> createUser(@RequestBody @Valid UserDto userDto) {
        // 유효성 검사를 통과한 경우 Created 응답 코드 보냄
        return ResponseEntity.status(HttpStatus.CREATED).body("사용자가 생성되었습니다.");
    }
}

 

4-4. 실행 결과

  • localhost:8080/api/users 에 POST 방식으로 아래의 요청 본문 (JSON 형태) 포함하여 요청 보냄
{
    "name": "",
    "email": "invalid-email",
    "id": "id123"
    "password": "123"
}
  • 응답 (JSON)
{
    "timestamp": "2024-08-13T12:34:56.789+00:00",
    "status": 400,
    "error": "Bad Request",
    "message": "이름은 필수로 입력해야 합니다, 이메일 주소가 유효하지 않습니다, 아이디는 6~12자리여야 합니다, 비밀번호는 8자리 이상이어야 합니다",
    "path": "/api/users"
}

 

5. 에러 메시지 설정 방법

  • Bean Validation → 어노테이션에 message 속성 추가하여 에러 메시지를 추가함
    • 동적인 에러 메시지 혹은 더 구체적인 에러 메시지 설정 방법
  • 혹은 위의 Spring Validation → 사용자 정의 Validator 클래스에서 정의한 사용자 정의 오류에 대한 구체적인 메시지 설정 방법

 

1. 프로젝트의 main/resources 폴더 안에 errors.properties 파일 생성

2. errors.properties 에 에러메시지 설정

    2-1. 에러코드=에러메시지

password.invalid=잘못된 비밀번호 입니다.

    2-2. (rejectValue(필드명, 오류코드, 오류메시지에 포함될 인자(배열 형태), 기본 오류메시지) → 에러메시지에 포함될 인자 사용)

age.min=나이는 {0}세 이상이어야 합니다.
저작자표시 변경금지 (새창열림)

'Spring Boot' 카테고리의 다른 글

[Spring Boot] 데이터 바인딩 예제 (@RequestParam, @ModelAttribute, @RequestBody)  (0) 2024.08.14
[Spring Boot] 스프링 AOP + 스프링 AOP를 사용한 예외 처리 (@Aspect, @ExceptionHandler, @(Rest)ControllerAdvice)  (0) 2024.08.14
[Thymeleaf] Thymeleaf 기본 문법 (+ 적용 방법)  (0) 2024.08.11
[Spring Boot] 프로젝트에 Swagger 적용, Swagger 어노테이션 정리  (0) 2024.05.11
[Spring Boot] 로그인 기능 구현 (9) - 자동 로그인 구현 (Spring Security - Remember Me)  (0) 2024.05.05
  1. 1. 유효성 검사
  2. 2. Spring Validation
  3. 3. Bean Validation
  4. 3-1. 유효성 검사 어노테이션 정리
  5. 3-2. 예제 코드
  6. 4. 통합 예제 (@Valid 사용)
  7. 4-1. build.gradle에 라이브러리 추가
  8. 4-2. UserDto
  9. 4-3. 컨트롤러
  10. 4-4. 실행 결과
  11. 5. 에러 메시지 설정 방법
'Spring Boot' 카테고리의 다른 글
  • [Spring Boot] 데이터 바인딩 예제 (@RequestParam, @ModelAttribute, @RequestBody)
  • [Spring Boot] 스프링 AOP + 스프링 AOP를 사용한 예외 처리 (@Aspect, @ExceptionHandler, @(Rest)ControllerAdvice)
  • [Thymeleaf] Thymeleaf 기본 문법 (+ 적용 방법)
  • [Spring Boot] 프로젝트에 Swagger 적용, Swagger 어노테이션 정리
공대생안씨
공대생안씨
전자공학과 학부생의 코딩 일기
티스토리
|
로그인
공대생안씨
공대생의 코딩 일기
공대생안씨
글쓰기
|
관리
전체
오늘
어제
  • All Categories (153)
    • Spring Boot (46)
      • JPA (7)
      • Lombok (2)
    • Java (21)
    • DevOps (3)
      • CI,CD (8)
      • Monitoring (2)
    • Database (7)
      • MySQL (5)
      • MongoDB (1)
      • H2 (1)
    • Trouble Shooting (5)
    • FE (4)
    • IntelliJ (3)
    • Git (3)
    • Algorithm (41)

블로그 메뉴

  • 홈
  • 태그
  • Github

공지사항

인기 글

hELLO · Designed By 정상우.v4.2.2
공대생안씨
[Spring Boot] 스프링 유효성 검사 Validation (@Valid, @Validated, Bean Validation)
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.