본문 바로가기
[IT]/SpringBoot

[Spring Boot] Controller - Dto 유효성 검사

by dop 2021. 4. 19.

Controller 설정

    @PostMapping("/users")
    @ApiOperation(value = "회원가입")
    public UserResponse joinUser(@Valid @RequestBody UserRequest request){
        return userService.save(request);
    }

위 코드는 @RestController로 선언된 Controller 클래스의 회원가입 메소드이다. @Valid 어노테이션을 추가하여 유효성 검사를 활성화 시킨다.

Dto 설정

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class UserRequest {
    private Long id;
    @Email(message = "Email 형식이 아닙니다.")
    @NotNull
    private String email;
    @NotNull(message = "값이 필요합니다.")
    private String password;
    @NotNull
    private String name;
    @NotNull
    private String nickname;
}

필드마다 설정이 가능하고, 사용가능한 어노테이션으로는 문자열 검증에는 @NotNull, @NotEmpty, @NotBlank(차이는 하단설명 참조) 등이 있고, 자주 사용하는 @Email, @Size, @Min, @Max 등이 있습니다.

  • @NotNull : null 이면 예외, 값을 설정하지 않은경우 예외.("" , " " 는 예외처리 X)
  • @NotEmpty : null, "" 을 예외로 판단.(" " 는 예외처리 X)
  • @NotBlank : null, "", " " 모두 예외로 판단.(가장 강력한 예외처리 방식)

400 Not Found!

여기까지만 해도 정상적으로 유효성 검사가 가능하다. 하지만,클라이언트 입장에서는 그저 '400 에러가 발생한 것'으로 밖에 판단 할 수 없고 어떤 값이 문제이고 어떤 문제인지 판단 할 수 없다. 이런 정보를 알리기 위해선 (message = "전송할 메세지")를 작성하고 ExceptionHandler를 선언하면 값이 반환될 때 해당 문자열이 같이 반환된다. (message는 어노테이션 인자값으로 사용하면 된다.)

ExceptionHandler 섷정

@RestControllerAdvice
public class ApiException extends RuntimeException{

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Map<String, String>> handleMethodArgumentNotValidException(MethodArgumentNotValidException e){
        Map<String, String> errors = new HashMap<>();
        e.getBindingResult().getAllErrors()
                .forEach(c -> errors.put(((FieldError) c).getField(), c.getDefaultMessage()));
        return ResponseEntity.badRequest().body(errors);
    }
}

RestController를 사용했기 때문에 @RestControllerAdvice 어노테이션을 사용한다. @Controller를 사용했다면, @ControllerAdvice를 사용하면 된다. @ExceptionHandler()부분에 처리할 예외클래스를 지정해주고, 메소드를 작성해주면, 해당 예외에 대해서는 message를 담아서 클라이언트한테 전송할 수 있다.

작성한 내용으로 전송

728x90