본문 바로가기
Spring

@ModelAttribute 그리고 @RequestParam

by invelog 2023. 8. 24.
반응형

@RequestParam

사용자가 요청 시 전달하는 값을 Handler(Controller)의 매개변수로 1:1 Mapping할 때 사용되는 어노테이션이다. 

@Controller
public class TestController { 
	@GetMapping("/")
    public String getTestPage(@RequestParam("name") String name) {
    	System.out.println("이름 : " + name);
        return "test";
    }
}

위와 같은 경우 사용자가 /?name=test 로 요청을 하게 되면, 위 Handler의 매개변수인 name에 "test"가 Mapping된다.

 

@ModelAttribute

사용자가 요청 시 전달하는 값을 Object 형태로 Mapping 해주는 어노테이션이다. 

@ModelAttribute는 메서드 레벨, 메소드의 파라미터에 적용이 가능하다. 이 글에서는 메서드의 파라미터에 사용되는 경우에 대해 이야기하겠다. 

@Getter
@Setter
public class TestModel {
	private String name;
    	private int age;
}

@RestController
public class TestController {
	@GetMapping("/")
    public String getTestPage(@ModelAttribute TestModel testModel) {
    	System.out.println("이름 : " + testModel.getName());
        System.out.println("나이 : " + testModel.getAge());
        return "test";
    }
}

위와 같은 경우, name, age를 인스턴스 변수로 가지는 TestModel 객체가 있고 이를 매개변수로 받기 위해 위와 같은 Controller를 생성한다. /?name=AA&age=17 로 요청을 하게 되면 각각 값이 Handler의 testModel 객체로 바인딩되게 된다. (단, Setter가 존재해야 한다)

 

결국 일대일 Mapping인지 객체 Mapping인지가 @RequestParam과 @ModelAttribute 어노테이션의 차이인데, @RequestParam으로 모두 전달받으면 되는데 특별히 @ModelAttribute로 사용자의 요청을 Mapping해야 할 필요가 있는가?

 

사용자를 찾기 위해 검색 조건을 요청에 담아 전달하는 경우를 예를 들어보면

 

@ModelAttribute를 사용하지 않는 경우

@RestController
public class TestController {
	@GetMapping("/")
    public String getTestPage(@RequestParam int id,
                              @RequestParam String name,
                              @RequestParam String email,
                              @RequestParam String phone,
                              Model model) {
    	List<User> userList = userService.search(id, name, email, phone);
        model.addAttribute("userList", userList);
        return "test";
    }
}

위와 같은 경우 사용자를 찾기 위한 검색 조건이 추가되거나 불필요해지게 되는 경우 Handler의 매개변수, userService.search() 호출 시 넘겨주게 되는 매개변수, UserService 클래스의 search() 메서드의 시그니처를 모두 변경해 주어야 하는데 이는 매우 비효율적이다.

또한, 매개변수가 많아졌을 때 매개변수의 타입이 같고 그 순서가 뒤바뀐다면 위험할 수 있다. 

 

@ModelAttribute를 사용하는 경우

@Getter
@Setter
public class UserSearchForm {
	private int id;
    	private String name;
    	private String email;
    	private String phone;
}

@RestController
public class TestController {
	@GetMapping("/");
    public String getTestPage(@ModelAttribute UserSearchForm userSearchForm,
                              Model model) {
    	List<User> userList = userService.search(userSearchForm);
        model.addAttribute("userList", userList);
        return "test";
    }
}

@RequestParam과 다르게 위와 같은 경우 검색 조건이 추가되더라도 UserSearchForm에 필드를 추가해 주면 Handler나 UserService의 search() 메서드의 시그니처를 수정할 필요가 없게 된다. 

 

 


 

참고 글

https://galid1.tistory.com/769

반응형

'Spring' 카테고리의 다른 글

Scheduler 처리  (1) 2023.10.26
VO에서 Map 변환 메서드 (Apache Util)  (2) 2023.08.31
@RequestMapping 이란?  (0) 2023.08.24
@Resource Annotation 이란?  (0) 2023.08.24
@Controller와 @RestController  (0) 2023.08.24