<목차>
1. 유효성 검사
2. @Valid 어노테이션 테스트
3. 유효성 검사 어노테이션
[유효성 검사]
애플리케이션의 비즈니스 로직이 올바르게 동작하기 위해, 데이터를 사전 검증하는 유효성 검사 작업이 필요하다.
유효성 검사란, 각 계층에서 들어오는 데이터에 대해, 의도한 형태대로 값이 들어오는지 체크하는 과정을 말한다.
계층별로 진행하는 유효성 검사의 경우, 검증 로직이 각 계층 클래스 별로 분산되어 있어 관리하기 어렵다는 문제가 있다.
또한 유효성 검사 로직 자체가 중복되는 경우가 많아, 불필요한 중복 소스가 발생하며, 검증해야하는 값이 많다면 코드 또한 몇 배로 길어지게 된다.
이런 문제를 해결하기 위해, JAVA 에서는 Bean Validation 이라는 프레임워크를 제공하고 있으며, 스프링 부트에서는 Bean Validation 의 구현체인 Hibernate Validator 를 유효성 검사의 표준으로 채택하여 사용하고 있다.
Hibernate Validator 는, 도메인 모델에서 어노테이션을 통해 필드값을 검증할 수 있도록 기능을 제공한다.
스프링 부트에서 유효성 검사는,
각 계층으로 데이터가 넘어오는 시점에, 해당 데이터에 대한 검사를 실시한다.
[@Valid 어노테이션]
유효성 검사를 위해 DTO 에 어노테이션을 통해 체크할 내용을 설정하고, 클라이언트로부터 넘어온 Request 에 대해 Controller 에서 유효성 검사를 실행하는지 확인해보자.
1. DTO 생성
<ValidRequestDto> DTO
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Builder
public class ValidRequestDto {
@NotBlank
String name;
@Email
String email;
@Pattern(regexp = "01(?:0|1|[6~9])[.-]?(\\d{3}|\\d{4})[.-]?(\\d{4})$")
String phoneNumber;
@Min(value=20) @Max(value=40)
int age;
@Size(min = 0, max = 40)
String description;
@Positive
int count;
@AssertTrue
boolean booleanCheck;
}
2. 컨트롤러 생성
<ValidationController> Controller
@RestController
@RequestMapping("/validation")
@Slf4j
public class ValidationController {
@PostMapping("/valid")
public ResponseEntity<ValidRequestDto> checkValidationByValidAnno(
@Valid @RequestBody ValidRequestDto validRequestDto) {
log.info(validRequestDto.toString());
return ResponseEntity.status(HttpStatus.OK).body(validRequestDto);
}
}
- 컨트롤러의 파라미터 부분을 보면, @Valid 어노테이션이 적용한 것을 확인할 수 있다.
3. 애플리케이션 실행 및 스웨거 접속
스웨거가 설정되어있지 않다면, Postman 과 같은 소프트웨어를 사용해도 무관하다.
** Swagger 설정 방법 **
[Springboot] springdoc 을 사용하여 Swagger 설정하기 - 1
1. Swagger ?2. springdoc - springfox3. Setting [Swagger ?]API를 개발함에 있어, 명세 관리는 필수이다.해당 API가 어떤 로직을 수행하는지 설명하고, 이 로직을 수행하기 위해 어떤 값을 필요로 하며, 이 로직
jh4dev.tistory.com
[Springboot] springdoc 을 사용하여 Swagger 설정하기 - 2
1. API 명세2. Schemas 명세 Springdoc OpenAPI 는 다양한 어노테이션을 활용해 API 문서를 쉽게 생성하고 관리할 수 있도록 해준다. 다음과 같은 Get API 기준으로 각종 어노테이션을 적용해보자. @GetMapping
jh4dev.tistory.com
4. 테스트
- 정상 케이스
- {
"name": "테스트",
"email": "test@test.com",
"phoneNumber": "010-4321-1234",
"age": 40,
"description": "설명",
"count": 1,
"booleanCheck": true
} - 결과 (Status 200)
- 실패 케이스
- age 의 최소값을 20으로 설정하였기에, 10으로 호출해보자.
{
"name": "테스트",
"email": "test@test.com",
"phoneNumber": "010-4321-1234",
"age": 10, // age 의 최소값을 20으로 설정하였기에, 10으로 호출
"description": "설명",
"count": 1,
"booleanCheck": true
} - 결과 (Status 400)
별다른 에러 처리를 하지 않았기에 Http Status Code = 400 으로 처리된 것을 확인할 수 있다.
- 로그도 살펴보자.
아래와 같이, 해당 필드에 대한 메시지까지 자동으로 생성되는 것을 확인할 수 있다.
[2024-08-14 15:54:20.416] [WARN ] [http-nio-8080-exec-3] org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity<cohttp://m.springboot.valid.data.dto.ValidRequestDto> cohttp://m.springboot.valid.controller.ValidationController.checkValidationByValidAnno(com.springboot.valid.data.dto.ValidRequestDto): [Field error in object 'validRequestDto' on field 'age': rejected value [10]; codes [Min.validRequestDto.age,Min.age,Min.int,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [validRequestDto.age,age]; arguments []; default message [age],20]; default message [20 이상이어야 합니다]] ]
[유효성 검사 어노테이션]
어노테이션
|
설명 | 적용 가능 타입 |
@NotNull | 해당 필드가 null이면 안되며 필수 입력 값 | 모든 참조 타입 (객체) |
@NotEmpty | 문자열이나 컬렉션이 비어 있으면 안된다.. (null과 빈 값을 모두 허용하지 않음) | String, Collection, Map, Array |
@NotBlank | 문자열이 공백을 포함한 빈 문자열이면 안된다. (공백만 있는 경우도 허용하지 않음) | String |
@Size | 문자열, 컬렉션, 배열 등의 크기나 길이를 제한한다. | String, Collection, Map, Array |
@Min | 숫자의 최소값을 제한한다. | int, long, short, byte, BigDecimal, BigInteger |
@Max | 숫자의 최대값을 제한한다. | int, long, short, byte, BigDecimal, BigInteger |
@Pattern | 정규 표현식으로 문자열 패턴을 제한한다. | String |
이메일 형식인지 검증한다. | String | |
@Digits | 숫자의 정수부와 소수부의 자릿수를 제한한다. | String, BigDecimal, BigInteger |
@Positive | 양수(0보다 큰 값)인지 검증한다. | int, long, short, byte, BigDecimal, BigInteger |
@PositiveOrZero | 양수 또는 0인지 검증한다. | int, long, short, byte, BigDecimal, BigInteger |
@Negative | 음수(0보다 작은 값)인지 검증한다. | int, long, short, byte, BigDecimal, BigInteger |
@NegativeOrZero | 음수 또는 0인지 검증한다. | int, long, short, byte, BigDecimal, BigInteger |
@Future | 해당 날짜가 미래인지 검증한다. | Date, Calendar, LocalDate, LocalDateTime, ZonedDateTime |
@Past | 해당 날짜가 과거인지 검증한다. | Date, Calendar, LocalDate, LocalDateTime, ZonedDateTime |
@FutureOrPresent | 해당 날짜가 미래이거나 현재인지 검증한다. | Date, Calendar, LocalDate, LocalDateTime, ZonedDateTime |
@PastOrPresent | 해당 날짜가 과거이거나 현재인지 검증한다. | Date, Calendar, LocalDate, LocalDateTime, ZonedDateTime |
@AssertTrue | 필드 값이 true인지 검증한다. | boolean, Boolean |
@AssertFalse | 필드 값이 false인지 검증한다. | boolean, Boolean |
@CreditCardNumber | 신용카드 번호 형식이 유효한지 검증한다. | String |
@Length | 문자열의 길이를 제한한다. @Size와 유사하지만, 주로 Hibernate Validator에서 사용된다. | String |
@Range | 숫자의 범위를 제한한다. @Min과 @Max의 대체로 사용된다. | int, long, short, byte, BigDecimal, BigInteger |
@URL | 유효한 URL 형식인지 검증한다. | String |
@Valid | 해당 필드가 포함된 객체가 유효한지 검증한다. 객체 필드 내의 어노테이션을 적용할 때 사용한다. | 모든 참조 타입 (객체) |
@Null | 해당 필드가 null이어야 함을 검증한다. | 모든 참조 타입 (객체) |
@DecimalMin | BigDecimal이나 BigInteger 타입의 최소값을 설정한다. @Min보다 정밀도를 지원한다. | BigDecimal, BigInteger, String, byte, short, int, long |
@DecimalMax | BigDecimal이나 BigInteger 타입의 최대값을 설정한다. @Max보다 정밀도를 지원한다. | BigDecimal, BigInteger, String, byte, short, int, long |
@PastOrPresent | 날짜가 과거 또는 현재인지 검증한다. | Date, Calendar, LocalDate, LocalDateTime, ZonedDateTime |
JAVA 에서 제공하는 @Valid 어노테이션 사용 방법에 대해 알아보았으며,
다음 포스팅에서는 스프링에서 지원하는 @Validated 어노테이션에 대해 알아보자.
'Spring & Spring boot' 카테고리의 다른 글
[Spring Boot] Validation - 4. 커스텀 Validation 설정하기 (0) | 2024.08.15 |
---|---|
[Spring Boot] Validation - 2. @Validated 어노테이션 사용방법 (0) | 2024.08.14 |
[Spring Boot] JPA - 8. 연관관계 매핑 (Relation) (0) | 2024.08.13 |
[Spring Boot] JPA - 7. QueryDSL 사용 방법 (0) | 2024.08.11 |
[Spring Boot] JPA - 6. QueryDSL 설정 (0) | 2024.08.11 |