Validation이란?
프로그래밍을 하는데에 있어서 가장 중요한 부분 중 하나
•
특히나 Java는 null 값에 대한 접근에 대해 NullPointerException 오류가 발행하기 때문에 이러한 부분을 예방하기 위해 Validation 즉, 검증 과정이 필요
•
Spring에서는 null 확인 뿐 아니라 문자의 길이 측정과 같은 다른 검증 과정도 쉽게 처리할 수 있도록 Bean Validation 제공
•
build.gradle : validation 의존성 주입
implementation 'org.springframework.boot:spring-boot-starter-validation'
Java
복사
Bean Validation
•
Bean Validation
◦
간편하게 사용할 수 있는 여러 애너테이션을 제공
@NotNull | null 불가 |
@NotEmpty | null, “” 불가 |
@NotBlank | null, “”. “ “ 불가 |
@Size | 문자 길이 측정 |
@Max | 최대값 |
@Min | 최소값 |
@Positive | 양수 |
@Negative | 음수 |
@Email | E-mail 형식 |
@Pattern | 정규 표현식 |
유효성 검사 예시
유효성 검사 대상 객체의 필드에 각 어노테이션을 추가해준다.
@Getter
public class ProductRequestDto {
@NotBlank
private String name;
@Email
private String email;
@Positive(message = "양수만 가능합니다.")
private int price;
@Negative(message = "음수만 가능합니다.")
private int discount;
@Size(min=2, max=10)
private String link;
@Max(10)
private int max;
@Min(2)
private int min;
}
Java
복사
컨트롤러에서 대상 객체를 매개변수로 받는 메소드를 통해 테스트를 진행한다. 이 때 대상 객체의 유효성 검사를 활성화 시키려면 @Valid 어노테이션을 붙여줘야 한다.
@Controller
@RequestMapping("/api")
public class ProductController {
...
// 유효성 검사 테스트용
// POSTMAN에서 해당 URL로 Cookie key:value 넣고 테스트해봐야 함. 오류로그에서 유효성검사 안된부분 확인 가능.
@PostMapping("/validation")
@ResponseBody
public ProductRequestDto testValid(@RequestBody @Valid ProductRequestDto requestDto) { // <- @Valid를 검사하고싶은 Dto에 붙여줘야 한다.
return requestDto;
}
}
Java
복사
POSTMAN으로 해당 URL을 통한 POST 요청 테스트에서 특정 필드의 값을 일부러 전달하지 않은 경우 다음과 같은 오류 메시지가 나타나게 된다.
2023-09-08T14:11:12.303+09:00 WARN 38250 --- [nio-8080-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public com.sparta.springauth.dto.ProductRequestDto com.sparta.springauth.controller.ProductController.testValid(com.sparta.springauth.dto.ProductRequestDto) with 2 errors: [Field error in object 'productRequestDto' on field 'name': rejected value []; codes [NotBlank.productRequestDto.name,NotBlank.name,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [productRequestDto.name,name]; arguments []; default message [name]]; default message [공백일 수 없습니다]] [Field error in object 'productRequestDto' on field 'email': rejected value [Robbiegmail.com]; codes [Email.productRequestDto.email,Email.email,Email.java.lang.String,Email]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [productRequestDto.email,email]; arguments []; default message [email],[Ljakarta.validation.constraints.Pattern$Flag;@730e5db2,.*]; default message [올바른 형식의 이메일 주소여야 합니다]] ]
Java
복사
예외처리를 통해 보다 쉽게 로그를 파악하기
위 오류 로그로는 개발자가 쉽게 알아보기 어렵고 사용자 입장에서도 어떤 문제인지 파악하기 어렵다. 컨트롤러 단계에서 유효성 검사에 대한 예외처리를 통해 쉽게 검사 오류에 대해 정리할 수 있고, 페이지를 이동 시킬 수도 있다.
회원 가입의 예시를 통해 유효성 검사 예외 처리를 진행해보았다. 우선 회원 가입에 사용되는 객체의 클래스인 SignupRequestDto.java에 위 유효성 검사 어노테이션을 사용하여 검사 대상들을 지정했다.
package com.sparta.springauth.dto;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class SignupRequestDto {
@NotBlank
private String username;
@NotBlank
private String password;
@Email
@NotBlank
private String email;
private boolean admin = false;
private String adminToken = "";
}
Java
복사
회원 가입 요청을 처리해주는 컨트롤러 UserController.java의 signup() 메소드의 내용이다. 마찬가지로 매개변수에 @Valid 어노테이션으로 위 Dto의 유효성 검사 대상들을 활성화 시켜준다. BindingResult 객체를 통해서 오류에 대한 정보를 담을 수 있으며 파라미터로 해당 메소드에 넣어준다. 그럼 BindingResult 를 통해 @Slf4j를 통해 로그를 기록하도록 한다.
@Slf4j
@Controller
@RequestMapping("/api")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
...
// 회원가입 API + 유효성검사
@PostMapping("/user/signup")
public String signup(@Valid SignupRequestDto requestDto, BindingResult bindingResult) {
// Validation 예외처리
List<FieldError> fieldErrors = bindingResult.getFieldErrors(); // 유효성 검사
if(fieldErrors.size() > 0) {
for (FieldError fieldError : bindingResult.getFieldErrors()) {
log.error(fieldError.getField() + " 필드 : " + fieldError.getDefaultMessage()); // 검사 실패 부분 로그로 확인하기
}
return "redirect:/api/user/signup"; // 검사 실패 시, 다시 회원가입 페이지로 이동
}
userService.signup(requestDto);
return "redirect:/api/user/login-page";
}
}
Java
복사
이제 서버를 실행하고 유효성 검사에 맞지 않는 테스트 값으로 회원 가입을 시도하면 다음과 같이 서버에서는 유효성 검사에 실패된 필드에 대하여 정리된 로그가 나타난다. 또한 검사 실패 시 redirect를 통해 회원 가입 페이지또는 원하는 경로로 갱신/이동 시킬 수 있다.
2023-09-08T14:30:40.589+09:00 ERROR 39760 --- [nio-8080-exec-5] c.s.s.controller.UserController
: email 필드 : 올바른 형식의 이메일 주소여야 합니다
2023-09-08T14:31:04.218+09:00 ERROR 39760 --- [nio-8080-exec-8] c.s.s.controller.UserController
: password 필드 : 공백일 수 없습니다
2023-09-08T14:31:04.218+09:00 ERROR 39760 --- [nio-8080-exec-8] c.s.s.controller.UserController
: email 필드 : 공백일 수 없습니다
2023-09-08T14:31:04.218+09:00 ERROR 39760 --- [nio-8080-exec-8] c.s.s.controller.UserController
: username 필드 : 공백일 수 없습니다
Java
복사