
이번에 버튼을 누르면 팝업 창을 띄워주는 기능을 구현하게 되었다.
이 때 버튼을 클라이언트가 누른다면 서버로 특정 값을 URL Parameter로 보내준다.
Server에서는 프론트엔드에서 보내주는 URL Parameter를 메서드 인자로 받고자 한다.
이 때 나는 Server단의 메서드 인자로 받기 위해 @ModelAttribute나 @RequestParam 어노테이션을 사용하였다.
내 생각으로는 이렇게 두 어노테이션이 사용된 경우에는 @RequestParam에 해당하는 변수에만 값이 주입될거라 생각했는데, DTO 내부의 name 변수에도 값이 주입 되었다.
어떻게 이게 가능했을까?
아래는 위 기능 설명에 대한 각색된 코드이다.
Frontend
document.addEventListener("DOMContentLoaded", function() {
var commandIdElements = document.querySelectorAll('.link-text');
commandIdElements.forEach(function(element) {
element.addEventListener('click', function() {
var modmNum = element.textContent;
var popupUrl = '/system/info.do?name=' + name;
window.open(popupUrl, 'popupWindow', 'width=1000, height=500');
});
});
});
Backend
@RequestMapping(value = "/system/info.do")
public String select(@ModelAttribute SelectDTO selectDTO, @RequestParam String name, HttpServletRequest request, HttpServletResponse response, ModelMap model) {
System.out.println("name : " + selectDTO.getName());
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SelectDTO {
private String name;
}
@ModelAttributes와 @RequestParam 모두 클라이언트로부터 넘어온 URL 파라미터를 JAVA 객체로 매핑한다.
예를 들어 Server로 “/system/info.do?name=hello” 라는 요청이 들어왔다고 가정하자.
이 때 @ModelAttribute는 Getter, Setter를 이용해 어노테이션이 지정된 객체에 URL 파라미터를 주입해준다.
즉 SelectDTO의 name 변수의 이름과 같은 URL 파라미터의 키 값인 name의 Value를 주입해준다.
이름이 다른 변수에 주입하고 싶다면 @ModelAttribute(”주입하고 싶은 변수 이름”)으로 직접 명시해주면 된다.
@RequestParam은 이와 다르게 어노테이션이 지정된 변수에 URL 파라미터를 주입해준다.
즉 @RequestParam String name 의 name에만 해당 값이 주입된다는 것이다.
위 특성들을 이야기 하면 왜 두 어노테이션의 객체, 변수에 값이 모두 주입 되었는지 이해할 수 있을 것이다.
@ModelAttributes와 @RequestParam 의 객체의 멤버 변수와 변수 모두 같은 URL Parameter이고, 각 변수명이 일치하기 때문에 각자에게 매핑이 된 것이다.