프레임워크(Framework)/Spring

[Spring MVC] 스프링 MVC @ModelAttribute 사용 방법 정리

잇트루 2022. 11. 18. 01:43
반응형
본 내용은 온라인 강의 사이트 인프런의 김영한 님의 강의 내용이 포함되어 있습니다.
'스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술'
 

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의

웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., -

www.inflearn.com

 

@ModelAttribute

개발을 하면 요청 파라미터를 받아서 필요한 객체를 만들고 그 객체에 값을 넣어주어야 한다.

스프링에서는 위 과정을 자동화해주는 @ModelAttribute 기능을 제공한다.

 

먼저, 요청 파라미터를 바인딩받을 객체를 만든다.

@Data
public class HelloData {
    private String username;
    private int age;
}

@Data : @Getter , @Setter , @ToString , @EqualsAndHashCode , @RequiredArgsConstructor를 자동으로 적용해준다.

 

@ModelAttribute를 사용하지 않는 경우

@ResponseBody
@RequestMapping("/model-attribute-v1")
public String modelAttributeV1(@RequestParam String username, @RequestParam int age) {
    HelloData helloData = new HelloData();
    helloData.setUsername(username);
    helloData.setAge(age);

		log.info("username={}, age={}", helloData.getUsername(), helloData.getAge());
		log.info("helloData={}", helloData);

    return "ok";

}

ModelAttribute를 사용하지 않는 경우 다음과 같은 과정을 통해 코드를 작성해야 한다.

  • @RequestParam을 통해 요청 파라미터를 받는다.
  • HelloData 객체를 생성하여 해당 객체에 username과 age 값을 넣는다.

 

@ModelAttribute를 사용하는 경우

@ResponseBody
@RequestMapping("/model-attribute-v1")
public String modelAttributeV1(@ModelAttribute HelloData helloData) {
    
    log.info("username={}, age={}", helloData.getUsername(), helloData.getAge());
    log.info("helloData={}", helloData);

    return "ok";

}

위 코드를 실행하면 자동으로 HelloData 객체가 생성되고, 요청 파라미터 값이 들어가 있는 것을 알 수 있다.

 

스프링 MVC는 @ModelAttribute가 있는 경우 다음과 같은 과정을 거치게 된다.

  • HelloData 객체를 생성한다.
  • 요청 파라미터의 이름으로 HelloData 객체의 프로퍼티를 찾는다.
  • 해당 프로퍼티의 setter를 호출하여 파라미터의 값을 입력한다.
  • 예를 들어, 파라미터 이름이 username이면 setUsername() 메서드를 찾아서 호출하여 값을 입력하는 것이다.

 

만약, int타입인 age에 숫자가 아닌 다른 값을 넣게 되면, BindException이 발생한다.

바인딩 오류를 처리하기 위해서는 이에 대한 검증 코드를 작성해야 한다.

 

(참고) 프로퍼티

객체에 getUsername(), setUsername() 메서드가 있으면, 해당 객체는 username이라는 프로퍼티를 가지고 있다.

username 프로퍼티의 값을 변경하면 setUsername()이 호출되고, 조회하면 getUsername()이 호출된다.

 

@ModelAttribute 생략

다음과 같이 @ModelAttribute는 생략할 수 있다.

@ResponseBody
@RequestMapping("/model-attribute-v2")
public String modelAttributeV2(HelloData helloData) {

    log.info("username={}, age={}", helloData.getUsername(), helloData.getAge());
    log.info("helloData={}", helloData);

    return "ok";

}

주의할 점

  • @RequestParam도 생략할 수 있어 혼란이 발생할 수 있다.
  • 스프링에서는 이러한 혼란을 방지하기 위해 다음과 같은 규칙을 적용하고 있다.
  • String, int, Integer와 같은 단순 타입의 경우 : @RequestParam
  • argument resolver로 지정해둔 타입 외의 나머지 : @ModelAttribute
반응형