본문 바로가기
Spring

@RequestParam vs @ModelAttribute vs @RequestBody

by 넬준 2022. 6. 24.

 

클라이언트로부터 온 요청에 포함된 메시지(정보)를 Spring에서 받기 위해 많이 사용하는 annotation에는 3가지가 있다.

 

@RequestParam
@ModelAttribute
@RequestBody

 

요청에 담긴 데이터가 어떤 형식이냐에 따라 사용하는 annotation이 다르다.

 

요청 데이터가 Query parameter일 때

쿼리 파라미터를 바인딩하기 위한 annotation은 @RequestParam@ModelAttribute이다.

/path?key1=value1&key2=value2 과 같이 url에 Query String으로 올 때는 물론이고, form 형식일 때에도 (Content-type : x-www-form-urlencoded) 요청 메시지 body에 Query String 형식으로 담겨오기 때문에 사용할 수 있다.

 

@RequestParam

 쿼리 파라미터 1개를 바인딩할 때 사용한다.

 required = true가 default이므로 반드시 필요한 파라미터가 아니라면 false로 설정해야 한다.

 

@ModelAttribute

 주로 여러 개의 쿼리 파라미터를 Dto와 같은 하나의 객체로 바인딩할 때 사용한다. 바인딩을 위해서는 (기본 생성자 + setter) 혹은 parameter를 갖는 생성자를 사용하기 때문에 클래스에 반드시 선언되어 있어야 한다. 단, parameter를 갖는 생성자를 선언했더라도, 기본 생성자가 선언되어 있고 setter가 선언되어 있지 않으면 바인딩이 되지 않는다.

 

 물론 뒤에 필드명을 붙여 쿼리 파라미터 1개만 받아올 수도 있다.

 

 

 

 

요청 데이터가 (주로) JSON일 때

 요청 메시지 body에 JSON형태로 데이터가 담겨올 때에는 @RequestBody를 사용해 Java 객체와 바인딩할 수 있다. @RequestBody를 붙여주면 Spring이 제공하는 MessageConverter 중 MappingJackson2HttpMessageConverter를 통해 JSON을 Java 객체로 변환한다(직렬화).

 

 변환 과정을 보면,

1. 기본 생성자로 객체를 생성하고,

2. Setter나 Getter 중 하나로 필드의 이름을 찾아 Reflection을 이용해 값을 할당한다.

 

그렇기 때문에 @RequestBody를 사용하는 dto 객체 클래스에는 값을 할당하기 위한 생성자(기본x)나 setter가 필요없다. (setter나 getter 중 하나는 이름을 알기 위해 필요하다.)

 

 

 


참고

 

https://tecoble.techcourse.co.kr/post/2021-05-11-requestbody-modelattribute/

https://mangkyu.tistory.com/72

https://parkadd.tistory.com/70

 

 

댓글