목록으로

기술 노트

[Spring] RESTful API를 위한 첫 조건 Validation, 유효성 검증

REST통신에서 서버가 데이터를 주고 받는 첫 번째 단계의 할 일은 가져온 데이터가 유효한지 검증 하는 과정이다.유효성 검증이란?API 서버로 들어온 데이터가 올바른 데이터인지 검증하는 과정을 말한다.  API 서버로 들어오는 데이터는 DTO( Data Transfer Object ) 형태로 들어오게 되는데, 이는 계층간 특별한 로직 없이 순수한 데이터 셋 만을 전송하기위해…

2024. 07. 12.0

REST통신에서 서버가 데이터를 주고 받는 첫 번째 단계의 할 일은 가져온 데이터가 유효한지 검증 하는 과정이다.

유효성 검증이란?

API 서버로 들어온 데이터가 올바른 데이터인지 검증하는 과정을 말한다.

API 서버로 들어오는 데이터는 DTO( Data Transfer Object ) 형태로 들어오게 되는데, 이는 계층간 특별한 로직 없이 순수한 데이터 셋 만을 전송하기위해 만들어진 객체이다.

Java에서 DTO를 검증하기 위해

@Valid와 @Validated

어노테이션을 메소드 매개변수 앞에 달아서 검증할 수 있다.

@Valid 어노테이션은 javax.validation 패키지에 포함되어있고

@Validated 어노테이션은 스프링 웹 org.springframwork.web.bind.annotation 패키지에 포함되어있다.

public User getUser(@Valid @RequestBody UserDto userDto){ return user(userDto); }

@Valid와 @Validation 어노테이션을 사용하면 어노테이션 객체 내부의 검증 패턴이 실행되는데,

주요 검증 어노테이션으로는

  • @NotNull: 값이 null이 아닌지 확인합니다.
  • @NotEmpty: 문자열이 null이 아니고, 길이가 0이 아닌지 확인합니다.
  • @NotBlank: 문자열이 null이 아니고, 공백이 아닌 문자가 하나 이상 포함되어 있는지 확인합니다.
  • @Size: 문자열, 컬렉션, 맵 또는 배열의 크기/길이를 제한합니다.
  • @Min: 숫자가 지정된 최소값 이상인지 확인합니다.
  • @Max: 숫자가 지정된 최대값 이하인지 확인합니다.
  • @Email: 문자열이 유효한 이메일 주소 형식인지 확인합니다.
  • @Pattern: 문자열이 지정된 정규 표현식과 일치하는지 확인합니다.
public class UserDto {

    @NotBlank(message = "Username is mandatory")
    @Size(min = 3, max = 20, message = "Username must be between 3 and 20 characters")
    private String username;

    @Email(message = "Email should be valid")
    @NotBlank(message = "Email is mandatory")
    private String email;

    @NotBlank(message = "Password is mandatory")
    @Size(min = 6, message = "Password must be at least 6 characters")
    private String password;

}

이런 식으로 사용할 수 있다.

추가적으로 스프링에서

@Validated는 유효성 검사 그룹을 지원하여 DTO객체 내의 인터페이스 형태의 그룹 검증을 구현할 수 있다.

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

public class UserDto {

    @NotBlank(message = "Username is mandatory", groups = Create.class)
    @Size(min = 3, max = 20, message = "Username must be between 3 and 20 characters", groups = Create.class)
    private String username;

    @NotBlank(message = "Email is mandatory", groups = {Create.class, Update.class})
    private String email;

    @NotBlank(message = "Password is mandatory", groups = Create.class)
    @Size(min = 6, message = "Password must be at least 6 characters", groups = Create.class)
    private String password;

    // Default group for general validation
    @NotBlank(message = "Name is mandatory", groups = Default.class)
    private String name;

    public interface Create {}
    public interface Update {}

    // Getters and setters
}
@RestController
@RequestMapping("/users")
public class UserController {

    @PostMapping("/register")
    public ResponseEntity<String> registerUser(
		@Validated(UserDto.Create.class) @RequestBody UserDto userDto
	) {
        // 서비스 로직 호출 등
        return ResponseEntity.ok("User registered successfully");
    }

    @PutMapping("/update")
    public ResponseEntity<String> updateUser(
		@Validated(UserDto.Update.class) @RequestBody UserDto userDto
    ) {
        // 서비스 로직 호출 등
        return ResponseEntity.ok("User updated successfully");
    }
}

이런식으로 생성DTO와 수정DTO 검증을 분할할 수 있다.

검증 실패

만약 검증에서 실패한다면 기본적으로

javax.validation의

ConstraintViolationException이 발생하고

스프링에서는 @RequestBody 혹은 @ModelAttribute 파라미터에 대해 검증이 실패하면

org.springframwork.web.bind의

MethodArgumentNotValidException이 발생한다.

따라서 해당하는 예외에 대해 적절한 처리가 이루어져야 한다.

댓글 0

loading comments...

[Spring] RESTful API를 위한 첫 조건 Validation, 유효성 검증