ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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

    댓글

Designed by Tistory.