<목차>
1. @Valid vs @Validated
2. @Validated 검증 그룹 지정하기
이전 포스팅에서, JAVA 에서 지원하는 @Valid 어노테이션에 대해 알아보았으며, 이번 포스팅에서는 스프링에서 지원하는 @Validated 어노테이션 사용법에 대해 알아보자.
[@Valid vs @Validated]
@Validated 는 기본적으로 @Valid 의 기능을 포함하고 있으며, 다음과 같은 차이가 있다.
항목 | @Valid | @Validated |
용도 | Java Bean Validation을 수행할 때 사용된다. 필드 또는 메서드 파라미터에서 사용된다. | Java Bean Validation을 수행하면서 특정 검증 그룹(Group)을 지정할 수 있다. |
적용 위치 | 필드, 메서드 파라미터, 생성자 파라미터 | 클래스, 메서드 파라미터, 생성자 파라미터 |
검증 그룹 지정 | 검증 그룹을 지정할 수 없습니다. 모든 기본 검증 규칙이 적용된다. | 검증 그룹을 지정할 수 있어, 특정 그룹에 대한 검증을 수행할 수 있다. |
주로 사용하는 곳 | JSR-303/JSR-380 Bean Validation에서 사용되며, Spring MVC 및 Spring Data에서도 지원된다. | Spring Framework에서 검증 그룹을 필요로 할 때 주로 사용된다. |
에러 발생 시 처리 | 발생한 유효성 검증 에러는 일반적으로 MethodArgumentNotValidException으로 처리된다. | 발생한 유효성 검증 에러는 ConstraintViolationException 또는 MethodArgumentNotValidException으로 처리된다. |
Spring 지원 여부 | Java Bean Validation 표준이므로 Spring 외의 환경에서도 사용 가능합니다. | Spring 프레임워크에서 주로 사용되는 어노테이션이다. |
위와 같은 내용 중, @Validated 의 검증 그룹을 지정하는 기능에 대해 알아보자.
[@Validated 검증 그룹 지정하기]
검증 그룹을 지정하기 위해서는, 마커 인터페이스를 생성하여 사용한다.
마커 인터페이스(Marker Interface) : 메서드를 가지지 않고, 특정 기능이나 속성을 표시하기 위해 사용되는 인터페이스
1. 마커 인터페이스 생성
public interface ValidationGroup1 {
}
public interface ValidationGroup2 {
}
2. 도메인 모델 내, 그룹 지정
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Builder
public class ValidatedRequestDto {
@NotBlank
String name;
@Email
String email;
@Pattern(regexp = "01(?:0|1|[6~9])[.-]?(\\d{3}|\\d{4})[.-]?(\\d{4})$")
String phoneNumber;
//Group1
@Min(value=20, groups = ValidationGroup1.class)
@Max(value=40, groups = ValidationGroup1.class)
int age;
@Size(min = 0, max = 40)
String description;
//Group2
@Positive(groups = ValidationGroup2.class)
int count;
@AssertTrue
boolean booleanCheck;
}
3. @Validated 어노테이션을 활용하여 컨트롤러 작성
@RestController
@RequestMapping("/validation")
@Slf4j
public class ValidatedController {
//@VALID
// @PostMapping("/valid")
// public ResponseEntity<ValidRequestDto> checkValidationByValidAnno(@Valid @RequestBody ValidRequestDto validRequestDto) {
//
// log.info(validRequestDto.toString());
//
// return ResponseEntity.status(HttpStatus.OK).body(validRequestDto);
// }
@PostMapping("/validated/group1")
public ResponseEntity<ValidatedRequestDto> checkValidationByValidatedAnnoGroup1(
@Validated(ValidationGroup1.class) @RequestBody ValidatedRequestDto validatedRequestDto
) {
log.info(validatedRequestDto.toString());
return ResponseEntity.status(HttpStatus.OK).body(validatedRequestDto);
}
@PostMapping("/validated/group2")
public ResponseEntity<ValidatedRequestDto> checkValidationByValidatedAnnoGroup2(
@Validated(ValidationGroup2.class) @RequestBody ValidatedRequestDto validatedRequestDto
) {
log.info(validatedRequestDto.toString());
return ResponseEntity.status(HttpStatus.OK).body(validatedRequestDto);
}
@PostMapping("/validated/all-group")
public ResponseEntity<ValidatedRequestDto> checkValidationByValidatedAnnoAllGroup(
@Validated({ValidationGroup1.class, ValidationGroup2.class})
@RequestBody ValidatedRequestDto validatedRequestDto
) {
log.info(validatedRequestDto.toString());
return ResponseEntity.status(HttpStatus.OK).body(validatedRequestDto);
}
}
- ValidationGroup1
- age 필드를 그룹으로 지정하였다.
- 따라서, age 필드를 제외한 다른 필드의 값이 유효하지 않더라도 성공으로 처리되는 것을 확인할 수 있다.
Request
{
"name": "", //@NotBlank 어노테이션이 적용되어있으므로 유효하지 않은 상태
"email": "123", //@Email 어노테이션이 적용되어있으므로 유효하지 않은 상태
"phoneNumber": "010-1234-1234",
"age": 40, // MAX 이하이므로 유효한 상태
"description": "string",
"count": 0,
"booleanCheck": true
} - /validated/group1 호출 결과
아래 좌측 이미지와 같이, name 과 email 필드가 유효하지 않은 상태임에도 불구하고 200 으로 리턴된걸 확인할 수 있다.
하지만, group1 로 설정된 age 를 유효하지 않게 호출하면, 우측과 같이 에러가 발생하는 것을 확인할 수 있다.
정리하자면, @Validated 어노테이션에 특정 그룹을 설정하는 경우에는, 지정된 그룹으로 설정된 필드에 대해서만 유효성 검사를 수행한다.
all-group 컨트롤러(checkValidationByValidatedAnnoAllGroup())와 같이, 여러 그룹을 지정할 수도 있으며, 마찬가지로 그룹들에 속한 필드들에 대해서만 유효성 검사를 수행한다.
'Spring & Spring boot' 카테고리의 다른 글
[Spring Boot] 예외 처리 - 1. ExceptionHandler 사용하기 (0) | 2024.08.15 |
---|---|
[Spring Boot] Validation - 4. 커스텀 Validation 설정하기 (0) | 2024.08.15 |
[Spring Boot] Validation - 1. @Valid 어노테이션 사용방법 (0) | 2024.08.14 |
[Spring Boot] JPA - 8. 연관관계 매핑 (Relation) (0) | 2024.08.13 |
[Spring Boot] JPA - 7. QueryDSL 사용 방법 (0) | 2024.08.11 |