[Spring] @RequestParam vs @ModelAttribute

artp·2025년 5월 21일

spring

목록 보기
7/11
post-thumbnail

@RequestParam vs @ModelAttribute

Spring MVC에서 컨트롤러가 클라이언트의 요청 데이터를 처리하는 방법은 다양합니다.
그중에서도 가장 많이 사용되는 두 가지 애노테이션인 @RequestParam@ModelAttribute의 차이점과 사용법을 알아보겠습니다.

개념 비교

@RequestParam@ModelAttribute는 모두 HTTP 요청에서 데이터를 추출하여 컨트롤러 메서드에 전달하는 역할을 하지만, 그 방식과 목적에는 차이가 있습니다.

애노테이션설명
@RequestParamHTTP 요청 파라미터(쿼리 스트링, 폼 필드 등)를 단일 변수로 바인딩
@ModelAttribute여러 요청 파라미터를 자바 객체(모델 객체)로 바인딩

바인딩 방식 차이

두 애노테이션의 가장 큰 차이점은 데이터를 바인딩하는 방식에 있습니다.

항목@RequestParam@ModelAttribute
바인딩 대상단일 값 (String, int 등 기본 데이터 타입)자바 객체 (DTO, Form 등)
전송 방식쿼리 스트링, 폼 필드쿼리 스트링, 폼 필드, URI 경로 변수, 요청 헤더
내부 처리요청 파라미터에서 값을 직접 추출객체 생성 후 setter로 각 필드 바인딩
필수 여부required=true가 기본값(파라미터 없으면 예외)객체의 필드는 기본값(null 또는 0)으로 설정
생략 가능 여부단순 타입 파라미터는 생략 가능클래스가 DTO이면 생략 가능

내부 동작 원리

@RequestParam 동작 방식

@RequestParamHTTP 요청 파라미터를 컨트롤러 메서드의 파라미터에 직접 바인딩합니다.
Spring은 내부적으로 RequestParamMethodArgumentResolver를 사용하여 이 작업을 처리합니다.

@GetMapping
public String setupForm(@RequestParam("petId") int petId, Model model) {
    Pet pet = this.clinic.loadPet(petId);
    model.addAttribute("pet", pet);
    return "petForm";
}
  • 요청 URL의 petId 파라미터 값을 추출하여 petId 변수에 바인딩합니다.

@ModelAttribute 동작 방식

@ModelAttribute는 요청 파라미터를 객체의 필드에 바인딩합니다.
Spring은 ServletModelAttributeMethodProcessor를 사용하여 이 작업을 처리합니다.

@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@ModelAttribute Pet pet) {
    // method logic...
    return "redirect:/owners/{ownerId}";
}
  • Pet 객체를 생성한 후, 요청 파라미터, URI 경로 변수, 요청 헤더에서 데이터를 추출합니다.
  • 추출된 데이터를 Pet 객체의 필드에 바인딩합니다.

실제 사용 예시

@RequestParam - 단일 값 바인딩

<form action="/search" method="get">
  <input name="keyword">
  <input name="page">
</form>
@GetMapping("/search")
public String search(@RequestParam String keyword,
                     @RequestParam(defaultValue = "1") int page) {
    // keyword: "스프링", page: 1
    return "searchResults";
}
  • 클라이언트가 ?keyword=스프링&page=1 형식으로 요청을 보내면, 각 파라미터가 컨트롤러의 개별 변수로 바인딩됩니다.
  • page 파라미터가 없을 경우 "1"이 기본값으로 사용됩니다.

@ModelAttribute - 모델 객체 바인딩

<form action="/register" method="post">
  <input name="name">
  <input name="email">
  <input name="age">
</form>
@PostMapping("/register")
public String register(@ModelAttribute MemberForm form) {
    // form.getName(), form.getEmail(), form.getAge() 자동 주입
    return "registerSuccess";
}

@Getter @Setter
public class MemberForm {
    private String name;
    private String email;
    private int age;
}
  • 클라이언트가 HTML 폼을 통해 보낸 모든 입력값MemberForm 객체의 필드에 자동으로 매핑됩니다.
  • 내부적으로는 new MemberForm()setter를 통해 각 값이 주입됩니다.
    폼 전체 데이터를 객체로 받을 때 유리한 방식입니다.

주의사항 및 팁

  1. @RequestParam

    • 기본적으로 필수 파라미터이므로, 선택적 파라미터는 required=false 설정 필요
    • 배열이나 컬렉션 타입으로 선언하면 동일한 이름의 여러 파라미터 값을 받을 수 있음
    • Map<String, String> 타입으로 선언하면 모든 요청 파라미터를 맵으로 받을 수 있음
  2. @ModelAttribute

    • 객체에는 기본 생성자와 setter 메서드가 필요함
    • 모델에 자동으로 추가되므로 뷰에서 바로 사용 가능
    • @SessionAttributes와 함께 사용하면 세션에서 객체를 가져올 수 있음

정리

@RequestParam@ModelAttribute는 모두 HTTP 요청 데이터를 처리하는 애노테이션입니다.
단일 값을 처리할 때는 @RequestParam이, 여러 필드를 가진 객체를 처리할 때는 @ModelAttribute가 더 적합합니다.

profile
donggyun_ee

0개의 댓글