인프런 커뮤니티 질문&답변

수빈님의 프로필 이미지
수빈

작성한 질문수

스프링 MVC 2편 - 백엔드 웹 개발 활용 기술

입력 폼 처리

postmapping 에서의 모델바인딩 객체

작성

·

370

·

수정됨

0

폼에서 작성한 데이터들이 @PostMapping("/add)로 넘어가서 @ModelAttribute 를 통해 item 객체에

요청 파라미터를 프로퍼티 접근법으로 값을 세팅하고 모델에 item 객체를 item 의 이름으로 바인딩 되는것이 맞죠?

맞다면, @ModelAttribute 를 통해 바인딩 되는 객체는

addForm 메소드에서 만들어주어서 타임리프에 활용가능하게 넘겨주었던 그 item 객체인가요?(같은 객체를 재사용하는건지) ,

아니면 새로운 객체를 또 만들어서 새로운객체에 값을 세팅해주고 모델에 바인딩을 해주는것인지 궁금합니다

 

수정폼에서

Item item = itemRepository.findById(itemId);

에서 찾는 item (entity?) 도 addForm 에서 새로 생성했던던 그 객체인것이죠?

답변 3

1

안녕하세요. 수빈님, 공식 서포터즈 OMG입니다.

1. addITem 메소드 호출시 바인딩 되는 객체와 동일한 객체인지

-> 프로퍼티 접근법으로 값이 세팅되며, 새로 생성된 서로 다른 객체입니다.

 

처리 담당 클래스 및 참조값으로 확인하는 방법

담당 클래스: HandlerMethodArgumentResolver인터페이스를 구현한 ModelAttributeMethodProcessor

 

참조값으로 확인

HTTP: GET addForm

@GetMapping("/add")
public String addForm(Model model) {
    Item item = new Item(); // item 인스턴스 생성하는 코드를 추출
    model.addAttribute("item", item);
    log.info("FormItemController.addItem: {}", item); // item 참조값 출력 추가
    return "form/addForm";
}

HTTP: POST addForm

@PostMapping("/add")
public String addItem(@ModelAttribute Item item, RedirectAttributes redirectAttributes) {
    log.info("FormItemController.addItem: {}", item); // item 참조값 출력 추가
    Item savedItem = itemRepository.save(item);
    redirectAttributes.addAttribute("itemId", savedItem.getId());
    redirectAttributes.addAttribute("status", true);
    return "redirect:/form/items/{itemId}";
}

두 참조값을 비교하는 방법으로 확인해볼 수 있습니다.

 

생성자 호출로 확인

public Item() {
    System.out.println("기본 생성자 호출");
}

Item클래스의 기본 생성자가 호출(새로운 객체 생성)되는 것으로도 확인해볼 수 있습니다.

 

2.editForm 메소드에서 findById 로 찾는 객체

-> 같은 객체입니다.

item을 저장소에 저장할 때 다음과 같이 store(map)에 Id(식별자)로 item 객체 그 자체를 저장하고,

public Item save(Item item) {
    item.setId(++sequence);
    store.put(item.getId(), item);
    return item;
}
public Item findById(Long id) {
    return store.get(id);
}
Item item = itemRepository.findById(itemId);

findById에서 Id(식별자)로 저장된 객체 자체를 반환하여 조회하기 때문에 같은 참조값을 가진 객체입니다.

 

  1. Item 객체가 단순히 자바빈으로 등록되어있는것이지

-> 네, Item 클래스는 자바 빈의 규약을 따르는 빈입니다.

 

감사합니다.

수빈님의 프로필 이미지
수빈
질문자

image

image

객체의 참조값이라는게 메모리 힙영역에 할당되어있는 메모리 주소값으로 알고있어

해쉬코드로 조회해보았더니 아래 이미지와 같이 다른 참조값이 나와 다른 객체임을 확인했으나,

알려주신 log.info("FormItemController.addItem: {}", item) 부분을 처음에 해보았더니,

같은 객체인지 아닌지 비교는 불가능하더라구요!

단순히 로그는 객체자체를 toString 해서 안의 데이터를 보여주는것 아닌가 해서요! ㅎㅎ(아래 이미지와 같이)

 image

log.info 로 참조값을 확인할수 있다는 말이 이해가 잘 가지 않습니다 ㅜㅜ..

번거롭게 질문드려서 죄송합니다.

 

답변에 대해 직접 확인해보는 것은 좋은 학습태도라 생각합니다 😀

추가로 말씀하신 내용의 경우 제가 설명을 빠뜨렸네요

Item클래스의 경우 @Data 어노테이션을 사용하였는데요,

@Data 에는 @ToString이 포함되어 있어 참조값을 출력하지 않습니다.

(직접 확인하신 사항과 같이 멤버변수 값을 출력)

 

Item 클래스의 @Data어노테이션을 지우고 @Getter와 @Setter만 추가하시면 참조값을 비교하실수 있습니다.

image

0

수빈님의 프로필 이미지
수빈
질문자

아!.. 제가 궁금한것은

/addForm()에서 생성된 빈 객체가

1. addITem 메소드 호출시 바인딩 되는 객체와 동일한 객체인지 와

  1. editForm 메소드에서 findById 로 찾는 객체

같은 객체인지 궁금합니다!

또한,

  1. Item 객체가 단순히 자바빈으로 등록되어있는것이지, 싱글톤은 아니죠?( 꼬리에 꼬리를 무는생각으로 이어진고민입니다.)

0

안녕하세요, 인프런 AI 인턴입니다.

수빈님께서 질문하신 내용과 관련하여 @ModelAttribute의 동작 원리와 사용 방식에 대해 설명해주는 유사한 질문의 답변을 찾았습니다. 해당 답변에서는 Model에 객체를 추가하고, 이를 th:object로 활용하는 과정 및 @ModelAttribute를 사용했을 때의 객체 바인딩에 대해 설명되어 있습니다.

아래 링크를 통해 확인하실 수 있습니다. 해당 내용이 수빈님의 궁금증을 해소하는 데 도움이 될 것입니다.

감사합니다.

수빈님의 프로필 이미지
수빈

작성한 질문수

질문하기