@ModelAttribute가 객체에 바인딩하는 과정 및 방법

@ModelAttribute

이 어노테이션은 보통 컨트롤러 메서드의 파라미터 객체의 앞에 사용되며

HTTP 요청을 받으면 HTTP 요청 파라미터를 자동으로 자바 객체에 바인딩 해준다.

요청을 처리하는 스프링 어노테이션으로 주로 @ModelAttribute와 @RequestBody가 많이 헷갈리는데
@ModelAttribute는 content-type이 application/x-www-form-urlencoded인 경우 즉 <form> 태그를 통해 제출한 데이터를 받아 객체로 변환하고,
@RequestBody는 message body를 통해 넘어온 JSON이나 XML 형식들을 받아 객체로 변환한다.

이 두 어노테이션에 대한 차이는 아래 포스팅을 참고하여 알아 볼 수 있다.
2023.07.05 - [JAVA/Spring] - [Spring] @ModelAttribute와 @RequestBody의 차이점에 대해 쉽게 이해해보자. (API 동작 방식)

 

이제 어떤 방식으로 @ModelAttribute가 자바 객체에 매핑을 해주는지 알아보자.


@ModelAttribute 바인딩 과정

HTML에서 form을 제출하는 코드가 다음과 같다고 가정해보자.

<form method="post" action="/join">
  <input type="textbox" name="userName" />
  <input type="textbox" name="userEmail" />
	<input type="textbox" name="userPwd" />
  <button type="submit">회원가입</button>
</form>

클라이언트가 회원가입 버튼을 누르면, input 태그의 userName과 userEmail의 값action의 경로 /join으로 method = post 요청을 보낸다.

(form에서 Get 방식은 URL에 쿼리 파라미터를 포함하여 전송하는 방식이고, Post 방식은 header의 body에 담겨 데이터를 전송, URL에 파라미터가 포함되지 않는다.)

 

그러면 이 폼데이터로 전송된 데이터가 어떻게 매핑 되느냐 ??

일단 UserController와 User Dto 코드를 보자.

UserController
@Controller
public class UserController {

    @PostMapping("/join")
    public String join(@ModelAttribute User user) {
    // ...
    }
}

 

User
@Getter
public class User {
    private String userName;
    private String userEmail;
    private String userPwd;
		
	@Builder
    public User(String userName, String userEmail, String userPwd) {
      this.userName= userName;
      this.userEmail= userEmail;
      this.userPwd= userPwd;
    }
}

@ModelAttribute 어노테이션 뒤에 온 User 객체에는 HTML에서 input 태그의 name 변수와 동일한 필드명인 것을 볼 수 있다.

그렇다 input 태그의 name 변수와 객체의 필드명이 동일하다면 Form을 통해 넘어온 데이터를 자동으로 바인딩 하는 것이다.


@ModelAttribute 어노테이션을 사용할 때 주의할점도 있다.

이에 대한 부분은 아래 포스팅에서 설명한다.

 

@ModelAttribute 객체가 바인딩 되지 않는 오류

 

hstory0208.tistory.com