본문 바로가기
Spring/Spring Framework

@ModelAttribute와 @RequestBody의 차이점

by YellowCow 2022. 9. 29.

개발 도중에

AJAX로 값을 전송할 일이 있었다

기존에 POST 메소드로 보냈던 AJAX 코드를 수정하여

값을 전송하는 코드를 작성했다

아래와 같이 AJAX로 전송을 시도했다

let testData={
    name:"garret",
    age:30
}
$.ajax({
    url: "http://localhost:8081/stringifyTest",
    type: 'GET',
    data: testData,
    contentType:"application/json; charset=utf-8"
}).done(function(){
    alert("성공");
}).fail(function(){
    alert("실패");
});

 

아래는 컨트롤러 코드이다

@RequestBody 어노테이션으로 값을 받도록 작성했다

@ResponseBody
@GetMapping("/stringifyTest")
public void stringifyTest2(@RequestBody PersonDto personInfo){
    log.debug("name: " + personInfo.getName());
    log.debug("age: " + personInfo.getAge());
}

 

아래 DTO 객체에 값을 매핑하여 받도록 했다

@Data
public class PersonDto {
    String Name;
    Integer age;
}

 

결론은 아무리 전송을 시도해도 컨트롤러에서 값을 전달받을 수 없었다

 

이유는 Spring Framework 공식 문서를 보고 알게 되었다

 

@RequestBody
You can use the 
@RequestBody annotation to have the request body read and deserialized into an Object through an HttpMessageConverter.

 

"@RequestBody 어노테이션을 사용하여 요청 본문을 읽고 객체에 매핑할 수 있습니다."

 

@RequestBody 어노테이션은 HTTP Message Body를 읽고 Body에 있는 값들을 객체에 매핑하게끔 한다

 

GET 메소드의 경우 전송할 값들이 URL에 담겨지고

그 URL은 HTTP Message Header에 담겨 보내진다

ex1. GET 메소드)

   GET /search?q=hello

 

ex2. POST 메소드)

이 때, @RequestBody 어노테이션으로 값을 전달 받을 수 없다

왜? 우리가 전달 받고자 하는 값은 HTTP Message Body가 아닌 Header에 존재하기 때문에..

 

@ModelAttribute를 사용하는 경우에는 가능하다

 

왜냐?  @ModelAttribute의 경우에는 값을 request parameter에서 가져오기 때문이다

request parameter는 GET/POST에 따라 읽어오는 위치가 각각 HTTP Message Body, Header로 달라지기 때문에

값을 읽어 올 수 있는 것이다

 

@ModelAttribute

The model attribute is also overlain with values from HTTP Servlet request parameters whose names match to field names.

 

"model 속성은 또한 필드 이름과 이름이 일치하는 HTTP Servlet 요청 매개변수의 값으로 오버레이됩니다."

 

 

 

앞으로는 @RequestBody 어노테이션을 사용할 때는 GET 메소드에서 사용하지 않도록 주의해야겠다 

 

댓글