Spring MVC에서 컨트롤러가 클라이언트의 요청 데이터를 처리하는 방법은 다양합니다.
그중에서도 가장 많이 사용되는 두 가지 애노테이션인 @RequestParam과 @ModelAttribute의 차이점과 사용법을 알아보겠습니다.
@RequestParam과 @ModelAttribute는 모두 HTTP 요청에서 데이터를 추출하여 컨트롤러 메서드에 전달하는 역할을 하지만, 그 방식과 목적에는 차이가 있습니다.
| 애노테이션 | 설명 |
|---|---|
| @RequestParam | HTTP 요청 파라미터(쿼리 스트링, 폼 필드 등)를 단일 변수로 바인딩 |
| @ModelAttribute | 여러 요청 파라미터를 자바 객체(모델 객체)로 바인딩 |
두 애노테이션의 가장 큰 차이점은 데이터를 바인딩하는 방식에 있습니다.
| 항목 | @RequestParam | @ModelAttribute |
|---|---|---|
| 바인딩 대상 | 단일 값 (String, int 등 기본 데이터 타입) | 자바 객체 (DTO, Form 등) |
| 전송 방식 | 쿼리 스트링, 폼 필드 | 쿼리 스트링, 폼 필드, URI 경로 변수, 요청 헤더 |
| 내부 처리 | 요청 파라미터에서 값을 직접 추출 | 객체 생성 후 setter로 각 필드 바인딩 |
| 필수 여부 | required=true가 기본값(파라미터 없으면 예외) | 객체의 필드는 기본값(null 또는 0)으로 설정 |
| 생략 가능 여부 | 단순 타입 파라미터는 생략 가능 | 클래스가 DTO이면 생략 가능 |
@RequestParam은 HTTP 요청 파라미터를 컨트롤러 메서드의 파라미터에 직접 바인딩합니다.
Spring은 내부적으로 RequestParamMethodArgumentResolver를 사용하여 이 작업을 처리합니다.
@GetMapping
public String setupForm(@RequestParam("petId") int petId, Model model) {
Pet pet = this.clinic.loadPet(petId);
model.addAttribute("pet", pet);
return "petForm";
}
petId 파라미터 값을 추출하여 petId 변수에 바인딩합니다.@ModelAttribute는 요청 파라미터를 객체의 필드에 바인딩합니다.
Spring은 ServletModelAttributeMethodProcessor를 사용하여 이 작업을 처리합니다.
@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@ModelAttribute Pet pet) {
// method logic...
return "redirect:/owners/{ownerId}";
}
Pet 객체를 생성한 후, 요청 파라미터, URI 경로 변수, 요청 헤더에서 데이터를 추출합니다.Pet 객체의 필드에 바인딩합니다.<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 형식으로 요청을 보내면, 각 파라미터가 컨트롤러의 개별 변수로 바인딩됩니다.<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;
}
new MemberForm() 후 setter를 통해 각 값이 주입됩니다.@RequestParam
required=false 설정 필요Map<String, String> 타입으로 선언하면 모든 요청 파라미터를 맵으로 받을 수 있음@ModelAttribute
@SessionAttributes와 함께 사용하면 세션에서 객체를 가져올 수 있음
@RequestParam과@ModelAttribute는 모두 HTTP 요청 데이터를 처리하는 애노테이션입니다.
단일 값을 처리할 때는@RequestParam이, 여러 필드를 가진 객체를 처리할 때는@ModelAttribute가 더 적합합니다.