정리/Spring

[Spring] 스프링 MVC 1편 7) 스프링 MVC 웹 페이지 만들기(2)

민발자 2023. 11. 10. 09:22
728x90

스프링 MVC 1편 백엔드 웹 개발 핵심 기술 

Session 7 스프링 MVC 웹 페이지 만들기

7. 상품 등록 폼

1) 속성 변경 th:action

th:action

상품 등록 폼의 URL과 실제 상품 등록 처리하는 URL을 똑같이 맞추고 HTTP 메서드로 두 기능 구분, 하나의 URL로 등록 폼과 등록 처리를 깔끔하게 처리 가능

상품 등록 폼 Get - /basic/items/add

상품 등록 처리 POST - /basic/items/add


8. 상품 등록 처리 - @ModelAttribute

1) @ModelAttribute

@ModelAttribute 이용해 한번에 처리

@PostMapping("/add")
public String addItemV2(@ModelAttribute("item") Item item, Model model) {
    itemRepository.save(item); 
    //model.addAttribute("item", item); //자동 추가, 생략 가능
    return "basic/item";
}

 

2) 요청 파라미터 처리

@ModelAttribute는 Item 객체를 생성하고 요청 파라미터 값을 프로퍼티 접근법으로 입력

 

3) Model 추가

모델에 @ModelAttribute로 지정한 객체를 자동으로 넣어줌

모델에 데이터를 담을 때 @ModelAttribute에 지정한 name 속성을 사용

 

4) @ModelAttribute 이름 생략

이름 생략하면 모델에 저장될 때 클래스명 사용

클래스의 첫 글자만 소문자로 변경해 등록 Item → item

 

5) @ModelAttribute 전체 생략

@PostMapping("/add")
public String addItemV4(Item item) {
  itemRepository.save(item);
  return "basic/item";
}

@ModelAttribute 자체도 생략 가능, 대상 객체는 모델에 자동 등록된다


9. 상품 수정

1) 리다이렉트

@PostMapping("/{itemId}/edit")
public String edit(@PathVariable Long itemId, @ModelAttribute Item item){
    itemRepository.update(itemId, item);
    return "redirect:/basic/items/{itemId}";
}

상품 수정 후 뷰 템플릿을 호출하는 대신 상세 화면으로 이동 → 리다이렉트 호출


10. PRG Post/Redirect/Get

1) 중복 등록

상품 등록을 완료하고 웹 브라우저의 새로고침 버튼을 클릭해 보면 중복 등록되는 버그가 있다.

웹 브라우저의 새로고침은 마지막에 서버에 전송한 데이터를 다시 전송

상품 등록 폼에서 데이터를 입력하고 저장을 선택하면 POST /add + 상품 데이터를 서버로 전송, 새로고침 하면 다시 전송

 

2) 중복 해결 PRG

상품 등록 후 뷰 템플릿으로 이동하는 것이 아니라 상품 상세 화면으로 리다이렉트 호출해 주면 된다.

새로 고침을 해도 상품 상세 화면으로 이동하게 되므로 새로 고침 문제를 해결할 수 있다.

이런 문제 해결 방식을 PRG라 한다.

@PostMapping("/add")
public String addItemV5(Item item) {
    itemRepository.save(item);
    return "redirect:/basic/items/" + item.getId();
}

item.getId()처럼 URL에 변수를 더해서 사용하는 것은 URL 인코딩이 안되기 때문에 위험 → redirectAttribute 사용


11. RedirectAttributes

1) RedirectAttribute

고객 입장에서는 상품 등록이 제대로 된것인지 애매함 → 저장되었습니다. 메시지 요구사항 추가

@PostMapping("/add")
public String addItemV6(Item item, RedirectAttributes redirectAttributes) {
    Item savedItem = itemRepository.save(item);
    redirectAttributes.addAttribute("itemId", savedItem.getId());
    redirectAttributes.addAttribute("status", true);
    return "redirect:/basic/items/{itemId}";
}

 

RedirectAttribute를 사용하면 URL 인코딩도 해주고 pathVariable, 쿼리 파라미터까지 처리해 준다.

pathVariable 바인딩 : {itemId}

나머지 쿼리 파라미터 처리 : ?status= rue

리다이렉트 할 때 status = true 추가

뷰 템플릿에서 이 값이 있으면 저장되었습니다 메시지 출력

 

<h2 th:if="${param.status}"th:text="'저장 완료!'"></h2>

th:if 해당 조건이 참이면 실행

${param.atatus} : 타임리프에서 쿼리 파라미터를 편리하게 조회하는 기능, 컨트롤러 모델에 직접 담고 값을 꺼내야 하지만 쿼리 파라미터는 자주 사용해서 타임리프에서 직접 지원

 

 

 

으아아 피곤하다 mvc도 완강...⭐️

728x90