-
Spring Boot - @ModelAttribute의 사용방법 및 주의사항Framework & Library/Spring Boot 2022. 3. 23. 11:44
@ModelAttribute
@ModelAttribute란?
Spring 프레임워크 환경에서 Request Parameter를 얻기 위해 "@ModelAttribute" 애너테이션을 자주 사용한다.
해당 애너테이션은 파라미터로 넘어온 값을 바인딩하여 개발자가 원하는 객체로 변환해주는 역할을 수행한다.
문제 상황
@Getter public class Person { private String name; private Long age; }
값을 바인딩하기 위한 객체인 Person 클래스는 name과 age 필드 두 가지를 가지고 있다.
@RequestMapping(value = "/getPerson.do", method = RequestMethod.GET) public String reqUrl(@ModelAttribute Person person) { System.out.println("이름 : " + person.getName() + ", " + "나이 : " + person.getAge()); return "테스트 완료"; }
컨트롤러에 위 코드와 같이 사용자로부터 넘어온 값을 처리하기 위한 메서드를 생성한다.
"@ModelAttribute" 애너테이션을 사용하면 파라미터 값을 원하는 객체로 쉽게 변환할 수 있는 장점이 있다.
컨트롤러와 매핑된 주소로 위 사진과 같은 요청을 수행하였다.
콘솔 창을 확인해본 결과 파라미터로 넘어온 값이 객체에 바인딩이 제대로 되지 않아 null 값을 가지고 있는 것을 확인하였다.
"@ModelAttribute" 애너테이션을 사용했음에도 불구하고, 값을 제대로 전달받지 못한 이유에 대해서 무엇일까?
@ModelAttribute의 동작 과정
@ModelAttribute의 바인딩 과정
Spring을 사용해본 사람이라면 위와 같은 문제가 발생한 이유에 대해서 알고 있을 것이다. 위와 같은 문제가 발생하는 이유는 "@ModelAttribute" 애너테이션은 값을 객체로 바인딩할 때 프로퍼티 접근법을 사용하기 때문이다.
Person person = new Person(); person.setName("홍길동"); person.setAge(20);
우리 눈에는 보이지 않지만 Spring MVC는 위와 같은 동작을 하고 있을 것이다. 우선, 기본 생성자를 사용해서 Person 객체를 생성한다. 그 다음 프로퍼티 접근법인 setter 메서드를 사용해서 넘어온 값을 객체에 주입하는 방식이다.
위에서 작성한 Person 클래스를 보면 getter 메서드만 존재하고, setter 메서드는 존재하지 않는다는 것을 확인할 수 있다. 따라서, 값을 바인딩하지 못해 null 값이 나오는 것이다.
앞서 보았던 문제를 해결해 주기 위해서는 위 사진과 같이 setter 메서드를 추가해주면 된다. (기본 생성자는 Java가 자동으로 생성함)
컨트롤러와 매핑된 주소로 다시 요청을 수행한다. Person 객체에 값이 제대로 바인딩되는 것을 확인할 수 있다.
setter 메서드를 사용하는 것이 꺼려진다면, 위 사진과 같이 setter 메서드를 지우고 모든 필드를 매개변수로 받는 생성자를 만들면 된다.
컨트롤러와 매핑된 주소로 요청을 수행하면, Person 객체에 값이 제대로 바인딩되는 것을 확인할 수 있다.
@ModelAttribute의 매핑 규칙
1. NoArgsConstructor와 AllArgsConstructor 둘 다 있는 경우
NoArgsConstructor를 호출하고, setter 메서드를 호출하여 파라미터 값을 객체 각각의 필드에 초기화한다.
2. AllArgsConstructor만 있는 경우
AllArgsConstructor를 호출하여 파라미터 값을 객체 각각의 필드에 초기화한다.
728x90'Framework & Library > Spring Boot' 카테고리의 다른 글
Spring Boot - HandlerMapping의 동작 방식 (0) 2023.01.30 Spring Boot - Swagger 라이브러리를 활용하여 API 문서 자동화하기 (0) 2023.01.19 Spring Boot - JUnit이란? (0) 2022.03.13 Spring Boot - Custom Exception (0) 2022.02.14 Spring Boot - @ControllerAdvice, @ExceptionHandler를 활용한 전역 예외 처리 (0) 2022.02.11