[Spring] Sptring Validation : 요청 데이터 유효성 검사

박재빈·2024년 10월 30일
0

1. Spring Validation 설정하기

Springboot 프로젝트에서 유효성 검증 기능을 사용하려면 spring-boot-starter-validation 의존성을 추가해야 한다. build.gradle에 다음과 같이 의존성 추가한다.

dependencies {
	// ...
    
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    
    // ...
}

2. Bean Validation 어노테이션 활용

Java Bean Validation에서는 여러가지 어노테이션을 사용하여 필드별 검증조건을 설정할 수 있다.

@Data
public class UserRequest {
    @NotBlank(message = "사용자 이름은 필수 항목입니다.")
    @Size(min = 2, max = 30, message = "사용자 이름은 2자 이상 30자 이하여야 합니다.")
    private String username;

    @Email(message = "유효한 이메일 주소를 입력하세요.")
    private String email;

    @NotBlank(message = "비밀번호는 필수 항목입니다.")
    @Size(min = 8, message = "비밀번호는 최소 8자 이상이어야 합니다.")
    private String password;

    @NotNull(message = "나이는 필수 입니다.")
    private Integer age;
}

어노테이션의 종류는 아래의 문서에 나와있으니 필요한 것을 찾아서 사용하면 된다.
https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/?v=8.0#validator-defineconstraints-spec

3. Controller에서 유효성 검사 적용하기

컨트롤러에서 @Valid 또는 @Validated 어노테이션을 사용하여 유효성 검사를 할 수 있다.

    @PostMapping
    public Object addUser(@RequestBody @Valid UserRequest userRequest) {
        log.info("API 컨트롤러 호출");
        log.info("성공 로직 실행");
        return userRequest;
    }

검증에 실패할 경우 MethodArgumentNotValidException이 발생한다.
BindingResult를 사용하면 검증에 실패해도 컨트롤러를 호출할 수 있다.

    @PostMapping
    public Object addUser(@RequestBody @Valid UserRequest userRequest, BindingResult bindingResult) {
        log.info("API 컨트롤러 호출");

        if(bindingResult.hasErrors()) {
            log.info("검증 오류 발생 errors = {}", bindingResult);
            return bindingResult.getAllErrors();
        }

        log.info("성공 로직 실행");
        return userRequest;
    }
  1. 요청 JSON을 UserRequest 객체로 생성
  2. UserRequest 유효성 검사
  3. 유효성 검사 실패한 내용은 bindingResult에 담긴다.
  4. bindingResult.getAllErrors()는 FieldError, ObjectError 모두 반환한다.
[
    {
        "codes": [
            "NotNull.userRequest.age",
            "NotNull.age",
            "NotNull.java.lang.Integer",
            "NotNull"
        ],
        "arguments": [
            {
                "codes": [
                    "userRequest.age",
                    "age"
                ],
                "arguments": null,
                "defaultMessage": "age",
                "code": "age"
            }
        ],
        "defaultMessage": "나이는 필수 입니다.",
        "objectName": "userRequest",
        "field": "age",
        "rejectedValue": null,
        "bindingFailure": false,
        "code": "NotNull"
    }
]

실제로는 필요한 데이터만 추출해서 API 응답을 해주면 된다.

0개의 댓글