dev.jaieve 공부기록

[SpringBoot] API 개발시 @RequestBody 객체 와 @Valid 어노테이션 본문

Back/Springboot

[SpringBoot] API 개발시 @RequestBody 객체 와 @Valid 어노테이션

제이브 2021. 7. 24. 21:32

Null 체크부터 Exception 까지의 흐름

DTO란?

Data Transfer Object의 약자로, 컨트롤 layer(controller)에서 받아온 데이터를 서비스 layer(service)로 넘겨줄 때 이용한다.

HTTP 통신시 API의 request와 response를 통해 Object가 호출된다. 하지만 Object의 domain에서의 여러 변수가 항상 필요하지는 않다.(ID만 가져오거나, nickname만 필요하거나 등등) API마다 request 및 response하는 parameter가 다르기 때문에 필요한 데이터만 정의되는 클래스가 필요하다. DTO가 바로 그 역할을 한다.

DTO에서 필수 값에 대한 조건 체크를 하는 것은 DTO에서 Domain으로 변환하는 로직이고, 요청된 Domain을 모두 response하는 것은 Domain에서 DTO로 변환되는 로직이다.

이 두 가지는 모두 DTO에 담겨야 한다.

DTO의 역할 : Data Validation

DTO class에서는 @NotNull, @NotEmpty 등과 같은 어노테이션으로 parameter의 Null 체크를 진행한다.

DTO에서 해당 어노테이션을 쓰는 경우, controller의 API 내부에서는 RequestBody에 @Valid 어노테이션이 추가되어야 Bean Validation을 사용할 수 있다.

@PostMapping("/login")
public ResponseEntity login(@Valid @RequestBody UserDTO loginUser) {    
    UserDTO login = userService.login(loginUser);
    return new ResponseEntity<>(new BaseResult.Normal(login), HttpStatus.OK);
}

 

Null 체크 어노테이션

API 개발시 request parameter의 null 체크를 할 때(DTO에서) Bean Validation이 제공하는 3가지 어노테이션을 이용할 수 있다.

  • @NotNull
  • @NotEmpty
  • @NotBlank

이 3가지는 사용방법이 유사하지만 결과가 다르기 때문에 유의해야 한다.

어노테이션 exception에 던져지는 경우 exception에 안걸리는 경우
@NotNull null "", " "
@NotEmpty null, "" " "
@NotBlank null, "", " "  

세 어노테이션의 사용방법은 다음과 같다.

~DTO.java

public class UserLoginRequestDto {
    @NotNull(message = "이름은 Null 일 수 없습니다!")
    @Size(min = 1, max = 10, message = "이름은 1 ~ 10자 이여야 합니다!") 
    private String name;

    @NotNull(message = "이메일은 Null 일 수 없습니다!")
    @Min(1)
    @Max(10)
    @Email
    private String email;
}
  • @Size : parameter의 최소(@Min), 최대(@Max) 사이즈를 지정할 수 있고, 해당 사이즈를 벗어나는 경우 message를 담아 예외로 던져진다.
  • @Email : 이메일 형식이 아닌 경우 예외로 던져진다.

위의 예시처럼 null체크 어노테이션에서 message 속성을 추가한다면, Exception을 던져질 때 함께 전달된다.

null 발생시 Bean Validation은 MethodArgumentNotValidExceptio 이란 예외가 던져진다. 던져진 예외는 @ExceptionHandler 라는 어노테이션으로 잡을 수 있다.

어노테이션으로 예외를 잡고나면, 다음의 코드를 통해 DTO에서 선언한 message 내용을 가져올 수 있다.

exception/~Exception.java

@ExceptionHandler(MethodArgumentNotValidException.class)
public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
    String errorMessage = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
		

		printExceptionMessage(errorMessage);
		//

		return new ResponseEntity<>(new BaseResult.Normal(INVALID_PARAMETER)
																, HttpStatus.BAD_REQUEST);
}

 

DTO에서 받은 message는 리턴하거나 Error log로 출력할 수 있다.


Reference

  1. https://sanghye.tistory.com/36
  2. https://jyami.tistory.com/55
반응형