메이쁘

[Spring] @RequestBody와 @ModelAttribute 의 차이 (feat. @RequestParam) 본문

Technology/Web - Spring

[Spring] @RequestBody와 @ModelAttribute 의 차이 (feat. @RequestParam)

메이쁘 2021. 4. 22. 23:49

안녕하세요.

 

서버를 구축하고, API 통신 예제를 만들던 중, POST 방식으로 객체에 값을 담아 Request 했는데 null만 뜨는 오류(+500 에러) 가 발생했었습니다.

 

이 때, @ModelAttribute를 사용했는데, 당최 어디서 오류가 나는지 아무리 찾아도 해결하지 못했습니다..

 

 

그러던 중, POST 방식이기 때문에 @RequestBody 를 사용해서 통신하면 되지 않을까 하고 했는데 200 결과를 얻었습니다!

 

 

 

이를 계기로 두 어노테이션의 차이점을 공부하고, 다음 번에는 이런 이슈가 발생하지 않기 위해서 기록하겠습니다.

 

 

 

 

@RequestBody


  - 클라이언트가 body에 application/json 형태로 값(보통 객체)을 담아 전송하면, body의 내용을 다시 Java Object(객체)로 변환해주는 역할을 수행합니다.

 

  - body에 담은 값을 변환하기 때문에, GET 이 아닌 POST 방식에서만 사용이 가능합니다. (GET 방식은 Header에 값을 담아서 보냅니다.)

 

  -  위에서 application/json 형태라고 언급했지만, XML 방식도 변환 가능합니다.

 

  -  이 데이터는 Spring에서 관리하는 MessageConverter들 중 하나인 MappingJackson2HttpMessageConverter를 통해 Java 객체로 변환된다고 합니다.

 

  -  body에 담긴 내용을 변환하기 때문에 @ModelAttribute 처럼 Setter 함수가 없어도 됩니다.

 

 

 

  예시)

  public ModelAndView login(HttpServletRequest request, @RequestBody SamplePVo pvo, BindingResult bindingResult) { }

 

JSON(body)에 객체를 담아서 POST 전송을 하면, 이 값을 객체로 변환해서 로직을 수행합니다.

 

 

 

@ModelAttribute


  -  클라이언트가 전송하는 HTTP parameter(URL 끝에 추가하는 파라미터), HTTP Body 내용Setter 함수를 통해 1:1로 객체에 데이터를 바인딩합니다. (Setter 필수!)

 

  -  HTTP Body 내용은 multipart/form-data 형태 입니다.

이걸 몰라서 application/json 형태로 @ModelAttribute를 주구장창하니, null만 출력할 수 밖에 없었죠.. 철이..없었죠

 

  -  위에 말한것처럼, 1:1로 객체에 데이터를 바인딩 하기 때문에 변수 타입이나 변수명 등 바인딩 가능한지 검증 작업이 이뤄집니다. 그래서 만약, 검증하다 걸리면 BindException을 뱉어냅니다..

 

  -  또한, JSP에서 Form 안에 input 값을 담아 보낼 때 유용하게 사용합니다.

 

  예시)

  public ModelAndView login(HttpServletRequest request, @ModelAttribute SamplePVo pvo, BindingResult bindingResult) { }

 

 

@ModelAttribute 어노테이션을 사용해서 500 Error(NullPointerException) 를 뱉어낸다..

 

 

 

@RequestParam


  -  HTTP 요청 parameter를 @RequestParam이 쓰이는 메소드의 변수로 Mapping 해주는 역할입니다.

 

  -  default는 required = true 이기 때문에, 필수적으로 작성한 이름에 해당하는 파라미터와 값이 들어와야합니다. 이를 해제하기 위해선 required = false 를 작성하면 됩니다.

 

예시)

  public ModelAndView login(HttpServletRequest request, @RequestParam("temp") String tempYo, BindingResult bindingResult) { }

 

 

세 가지의 어노테이션 차이를 알아봤습니다.

 

이제 서버 개발할 때 바로바로 만들 수 있겠죠?!

 

 

감사합니다.

 

 

 

 

 

 

참고

mangkyu.tistory.com/72

juyoungit.tistory.com/286

dionysus2074.tistory.com/172

 

Comments