Blog

[Spring]44 SpringBoot에서의 Validation 유효성 검사와 로그

Category
Author
Tags
PinOnMain
1 more property
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.javasignup() 메소드의 내용이다. 마찬가지로 매개변수에 @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
복사