스프링에서 어노테이션 검증을 사용하면 별도의 로직없이 setter가 작용할 때(컨트롤러에 들어오기에도 전) 바로 변수 검증을 진행한다. 인입 로그 없이 에러가 나서 당혹스러울 수는 있지만 잘못된 변수가 들어와서 문제를 일으킬 우려를 아애 차단하는 방법이다.
가장 유명한 어노테이션 모듈은 javax.validation.constraints 가 제공하는 어노테이션인데 요즘에는 jetbrain이나 롬복에서도 비슷한 기능의 어노테이션이 있는 듯하다(비슷한 이름도 많아서 import 할 때 잘 봐야 한다).
springboot2.3 이후부터는 javax 모듈을 포함하던 어노테이션 검증자가 'org.springframework.boot:spring-boot-starter-web' 에서 제외되어 별도의 dependency가 필요하다.
implementation 'org.springframework.boot:spring-boot-starter-validation'
javax.validation.constraints 에서 제공하는 문자열 검증에 많이 쓰이는 세 가지 어노테이션(@NotNull, @NotEmpty, @NotBlank)과 롬복에서 제공하는 @NonNull 어노테이션을 같이 비교해본다.
null | "" (empty string) | " " | 허용 타입 | |
@NotNull | invalid | valid | valid | all |
@NotEmpty | invalid | invalid | valid | CharSequence Collection Map Array |
@NotBlank | invalid | invalid | invalid(trimmed length > 0) | CharSequence (String) |
@NonNull | invalid | valid | valid |
위 표에서 간단하게 명시하긴 했지만, @NotNull, @NotEmpty, @NotBlank 와 @NonNull은 사실 쓰임이 다르다.
@NotNull, @NotEmpty, @NotBlank가 허용된 타입의 변수에 대한 확인이라면, @NonNull은 null-check 로직을 자동으로 생성해주는 애노테이션이다.
생성자, 메소드 특정 파라미터에 @NonNull이 달려있으면 롬복은 자동적으로 해당 파라미터에 대한 null check 코드를 생성한다. 이때 null check 코드는 메서드나 생성자의 최상단에 위치한다. 또, 필드에 @NonNull이 달려있으면 해당 필드에 값을 설정하는 메서드들에도 null check 코드를 생성한다.
아래는 구현 예시이다.
public ResponseEntity<Flux<HolderAccountSummary>> getAccountInfoSubscription(@PathVariable(value = "id") @NonNull @NotBlank String holderId){
return ResponseEntity.ok()
.body(queryService.getAccountInfoSubscription(holderId));
}
이렇게 짜놓으면 빌드 클래스에는 아래와 같이 null check 코드가 추가되어 있다.
public ResponseEntity<Flux<HolderAccountSummary>> getAccountInfoSubscription(@PathVariable("id") @NotBlank @NonNull String holderId) {
if (holderId == null) {
throw new NullPointerException("holderId is marked non-null but is null");
} else {
return ResponseEntity.ok().body(this.queryService.getAccountInfoSubscription(holderId));
}
}
null check 코드가 추가되었는데도 변수 앞에 @NonNull은 왜 안 지워져 있고 그대로인지는 의문이다..
참고로 javax.validation.constraints 라이브러리에 null 체크 말고도 어노테이션으로 검증할 수 있는 것들이 많은데(size, positive, negative, future, email, digits, assertTrue, etc.) 그때그때 찾아보면서 사용해야겠다.
참고: https://jyami.tistory.com/55
@Valid 를 이용해 @RequestBody 객체 검증하기
Springboot를 이용해서 어노테이션을 이용한 validation을 하는 방법을 적으려 한다. RestController를 이용하여 @RequestBody 객체를 사용자로부터 가져올 때, 들어오는 값들을 검증할 수 있는 방법을 소개한
jyami.tistory.com
롬복 어노테이션: daleseo.com/lombok-useful-annotations
'개발 > spring' 카테고리의 다른 글
[logback] Reflective setAccessible(true) disabled (0) | 2022.03.16 |
---|---|
[spring] filter vs OncePerRequestFilter vs interceptor (0) | 2022.03.02 |
[개념] interceptor vs filter 그리고 ContentCachingRequestWrapper (0) | 2022.02.10 |
[retry] spring-retry test code (1) | 2022.02.07 |
[retry] spring-retry for auto retry (0) | 2022.02.04 |