Validation이란?
Validation이란 프로그래미에 있어서 가장 필요한 부분이다. 특히 Java에서는 null 값에 대해서 접근 하려고 할 때
NullPointerException이 발생 함으로, 이러한 부분을 방지하기 위해서 미리 검증하는 과정을 Validation 이라고 한다.
이름과 비밀번호 나이가 입력으로 들어온다 했을 때, 단순하게 생각하면
public void validate(String name, String pwd, int age) {
if(name == null || pwd == null) {
return;
}
if(age == 0) {
return;
}
// logic
}
위와 같이 작성할 수 있을것이다.
하지만 위와 같은 코드들이 반복될 수록 아래와 같은 문제가 생길 수 있다.
1. 검증해야할 값이 많은 경우 코드의 길이가 길어 진다.
2. 구현에 따라서 달라 질 수 있지만 Service Logic과 분리가 필요하다.
3. 흩어져 있는 경우 어디에서 검증을 하는지 알기가 어려우며, 재사용의 한계가 있다.
4. 구현에 따라 달라질 수 있지만, 검증 Logic이 변경 되는 경우 테스트 코드 등
참조하는 클래스에서 Logic이 변경되어야 하는 부분이 발생할 수 있다.
Spring Boot에서 Validation
Spring Boot에서는 Validation을 Annotation을 사용하여 일관적으로 제공해준다.
Annotaion | 내용 |
@Size | 문자 길이 측정 |
@NotNull | null불가 |
@NotEmpty | null, ""불가 |
@NotBlank | null, "", " " 불가 |
@Past | 과거 날짜 |
@PastOrPresent | 오늘이나 과거 날짜 |
@Future | 미래 날짜 |
@FutureOrPresent | 오늘이거나 미래 날짜 |
@Pattern | 정규식 적용 |
이메일 형식 확인 | |
@Max | 최대값 |
@Min | 최소값 |
@AssertTrue/ False | 별도 Logic 적용 |
@Valid | 해당 Object Validation 실행 |
하지만 이러한 Validation들은 기본적으로 제공해주는 것이 아니라서 gradle dependecies가 필요하다.
implementation("org.springframework.bot:spring-boot-starter-validation")
위의 dependecies를 추가했으면 이제 사용을 할 수 있다.
User class로 예시를 들자면
public class User {
private Long id;
@NotBlank
private String name;
@Min(value = 1)
private int age;
@Pattern(
regexp = "^\\d{2,3}-\\d{3,4}-\\d{4}$",
message="핸드폰 번호는 000-0000-000 형식이여야합니다."
)
private String phoneNumber;
@NotBlank
private String loginId;
@Pattern(regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,10}$")
private String password;
@Email
private String email;
// yyyyMMdd로 들어오는 날짜
@Size(min=8, max=8)
private String reqDate;
// reqDate에 대한 validation 로직 작성
// 필드 변수에 대한 validation작성시 is+필드변수명+Validation을 항상 붙여서 만들어야함
@AssertTrue
public boolean isReqDateValidation() {
try {
LocalDate.parse(getReqDate(), DateTimeFormatter.ofPattern("yyyyMMdd"));
} catch(Exeption e) {
return false;
}
return true;
}
}
와 같이 사용할 수 있다.
Annotation을 붙였다고 User클래스를 사용할 때마다 검증이 되는 것은 아니다. 검증하기 위해서는 사용하는 곳에 @Valid를 붙여야 Annotation에 대한 검증이 시작된다.
@PostMapping("/user")
// @Valid Annotation을 붙여서 검증 요청
public ResponseEntity User(@Valid @RequestBody User user, BindingResult bindingResult) {
StringBuilder sb = new StringBuilder("");
if(bindingResult.hasErrors()) {
bindingResult.getAllErrors.forEach(objectError -> {
FieldError field = (FieldError) objectError; // Error 발생 필드
String message = objectError.getDefaultMessage(); // Error 메시지
sb.append("field : " + field.getField());
sb.append("message : " + message);
})
}
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(sb.toString());
}
Controller에서 일부를 가져왔다.
위 코드는 @Valid로 검증을 요청하고 Error가 발생할 시 BindingResult로 Error를 가져와서 Error발생 필드와 해당 메시지를 가져와서 Status에 Body로 내려주는 코드이다.
위와 같이 User클래스를 받는 곳에 @Valid를 붙여야 사용할 수 있다.
그 외에도 Path Parameter에도 적용 시킬 수 있는데 이는 클래스에 작성한 것과는 비슷하게 작성해야한다.
클래스에 @Validated를 붙이고 객체 사용한 것 처럼 작성하면 된다.
@RestController
@RequestMapping("/api")
@Valitdated
public class RestApiController {
@GetMapping("/get/{id}")
public String get(
@Size(min=1)
@PathVariable Long id,
@NotNull
@RequestParam String name
) {
return id + " " + name;
}
}
또한 만약에 Mapping관계에 있는 클래스에도 @Valid를 사용해야 해당 클래스를 가져올 때 @Valid가 적용이 된다.
public class User {
// logic
@Valid
List<Board> boards;
}
※ 만약에 @Valid가 없으면 User가 들어오면서 Board가 같이 들어왔을 때, Board에 Validation이 붙어 있다 하더라도 검증을 진행하지 않아 ""나 null에 대한 처리를 하지 않게된다.
'Back-End > Spring Boot' 카테고리의 다른 글
Spring Boot Filter란 (2) | 2024.06.16 |
---|---|
Spring Boot @RestControllerAdvice를 이용한 예외 처리 방법 (0) | 2024.06.09 |
AOP (0) | 2024.06.08 |
IoC와 DI (0) | 2024.06.08 |
Spring Boot Custom Validation만들기 (0) | 2024.06.07 |