티스토리 뷰

스프링

@RequestBody 데이터 검증하기

김쓰로그 2022. 11. 4. 19:35

이전에 간단한 게시판을 만들거나 했을 때는 HTML의 form 태그를 이용하여 데이터를 POST 했고 이를 @ModelAttribute를 통해 전달받았습니다. 그리고 @Validated, BindingResult를 통해 검증을 하고 오류가 있다면 다시 이 전의 등록폼으로 이동하는 방식으로 데이터를 검증했습니다.

 

그런데 이번에 블로그 프로젝트를 하는데에 게시글 또는 댓글 등을 POST 하는데 있어서 저는 AJAX 방식을 사용했고 이때는 @ModelAttribute가 아닌 @RequestBody 어노테이션을 사용했어야 했습니다. 그래서 이 때는 어떻게 데이터를 검증해야할까? 라는 생각에 공부를 하고 이를 기록해볼까 합니다.


간단한 코드 작성과 잘못된 입력의 결과

 

간단한 API를 작성해보겠습니다.

간단한 컨트롤러
DTO

@NotNull : 전달된 값이 NULL이면 안된다.

@Length : 길이를 제한할 수 있다.

@Email : 이메일의 형식을 맞춰야한다.

(Bean Validation에 대해서는 공식문서에 자세하게 나와있습니다.)

 

위 DTO에서 설정한대로 값을 보내지 않으면 어떻게 될까요?

포스트맨에서는 바로 400오류가 응답으로 들어오고 인텔리제이에서도 스프링 자체 오류 메시지를 띄어줍니다.

 

아래는 스프링 자체 오류 메시지 입니다. 

더보기

2022-11-04 18:54:13.408  WARN 18932 --- [nio-8080-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity<java.lang.String> api.validation.controller.TestController.saveArticle(api.validation.dto.ArticleDto) with 2 errors: [Field error in object 'articleDto' on field 'email': rejected value [asd123]; codes [Email.articleDto.email,Email.email,Email.java.lang.String,Email]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [articleDto.email,email]; arguments []; default message [email],[Ljavax.validation.constraints.Pattern$Flag;@25144b27,.*]; default message [올바른 형식의 이메일 주소여야 합니다]] [Field error in object 'articleDto' on field 'title': rejected value [hiiiiiiiiii!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!]; codes [Length.articleDto.title,Length.title,Length.java.lang.String,Length]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [articleDto.title,title]; arguments []; default message [title],20,0]; default message [길이가 0에서 20 사이여야 합니다]] ]

<정보>

server.error.include-message=always
server.error.include-stacktrace=never
server.error.whitelabel.enabled=true
server.error.include-binding-errors

스프링 부트에서는 위의 설정등을 통해 좀 더 많은 정보를 전달할 수도 있지만 모든 오류 정보를 사용자에게 직접 노출하면 위험하다고 들었습니다. 따라서 필요한 정보만을 전달해야합니다.

 

그럼 어떻게 예외정보만을 데이터로 넘겨야 할까요?


예외 로그를 보면 아래와 같습니다.

MethodArgumentNotValidException 예외가 터진것을 볼 수 있습니다.

이를 잡아서 해결해주면 되는 것입니다.

API를 잡기 위해서는 @ExceptionHandler 어노테이션을 사용하면 됩니다.

위의 코드를 설명하자면 이렇습니다.

  • @RestControllerAdvice
    • 예외처리를 해주는 컨트롤러 명시 
    • 특정 대상을 따로 지정하지 않으면 글로벌하게 모든 컨트롤러에 대해 적용된다.
  • @ExceptionHandler
    • API 예외 처리 문제를 해결하기 위한 어노테이션
    • @ExceptionHandler(예외클래스)와 같이 예외를 처리지정해 주는데 이는 생략하면 파라미터로 들어가 있는 예외로 자동으로 지정된다.

그럼 위와 같이 JSON 응답을 보냅니다.(여기서 ErrorDto는 제가 임의로 만든 것입니다.)

 

위에서 조금 응용하면 여러 필드에 대한 오류도 잡아 JSON으로 보낼 수 있습니다.

HashMap을 통해 key는 필드의 이름을 value는 기본 오류메시지로 설정해 응답합니다.

그럼 위와 같이 응답을 받을 수 있고 이를 활용하여 클라이언트에게 오류를 보여줄 수 있습니다.


작성한 코드

https://github.com/StartDeveloperKim/Kim-s-Java-Study/tree/main/validation

 

GitHub - StartDeveloperKim/Kim-s-Java-Study: 여러 공부 파일 입니다.

여러 공부 파일 입니다. Contribute to StartDeveloperKim/Kim-s-Java-Study development by creating an account on GitHub.

github.com

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함