상품등록 후 새로고침하면 중복등록이 되는 문제가 발생
[실제 상품을 등록한 뷰 화면]

위처럼 상품 등록한 상태에서 새로고침을 누른다면 상품ID는 계속 올라가고 상품이 계속 등록되는 이슈가 생긴다.
[상품등록 POST - BasicItemController ]
@PostMapping("/add")
public String addItemV4(Item item){
itemRepository.save(item);
return "basic/item";
}
- 전체 흐름
- 실제 상품등록
- 상품 상세 뷰로 뷰템플릿(basic/item)을 호출 - 끝
- 상품 등록 (POST / add) URL 이 유지되어있는 상태
- 새로고침하면 계속 POST / add 행위가 지속된다.
- 새로고침 시 마지막 행위가 다시 요청되기 때문에 상품이 중복저장이 되는 이슈가 발생한다.
-
문제 해결 방법은 리다이렉트!
POST ▶ Redirect ▶ GET
실제 상품을 등록하고 뷰 템플릿으로 호출하는게 아니라 상품 상세화면으로 리다이렉트를 하면된다.
그렇게 하면 상품 등록 후 상품 상세 화면으로 다시 이동해서 (리다이렉트) 마지막에 호출한 GET /items/{id} 이 된다.

- 전체 흐름
- 실제 상품등록 POST/ add
- 상품 상세 화면으로 리다이렉트 Redirect items/{itemId} 호출 http://localhost:8080/basic/items/3
- 웹 브라우저가 상품 상세를 새로 요청 GET /items/{id}
- 새로고침을 해도 GET /items/{id} 상품 상세 화면으로 이동
- 문제 해결
[상품등록 POST redirect - BasicItemController ]
@PostMapping("/add")
public String addItemV5(Item item) {
itemRepository.save(item);
return "redirect:/basic/items/" + item.getId();
}
※ 주의
+item.getId() 처럼 URL에 변수를 더해서 사용하는 것은 URL 인코딩이 안되기 때문에 위험
RedirectAttributes
RedirectAttributes 을 사용하여 URL 인코딩 문제 해결과 상품이 실제로 등록이 됐을때 "저장되었습니다." 메세지가 나오도록 해보자
@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}";
}
RedirectAttributes 는 리다이렉트할 때 모델에 데이터를 전달할 수 있고 파라미터에 itemId와 status 를 붙여주는 역할이다.
- basic/items/1?status=true
이제 저장완료 메세지를 만들어보자
리다이렉트 redirect:/basic/items/{itemId} ▶ 최종 basic/item 뷰 템플릿을 호출한다.
@Controller
@RequestMapping("/basic/items")
@RequiredArgsConstructor
public class BasicItemController {
private final ItemRepository itemRepository;
//상품 상세
@GetMapping("/{itemId}")
public String item(@PathVariable Long itemId, Model model){
Item item = itemRepository.findById(itemId);
model.addAttribute("item", item);
return "basic/item";
}
....
뷰템플릿
resources/templates/basic/item.html
상품 상세
<div class="container">
<div class="py-5 text-center">
<h2>상품 상세</h2>
</div>
<!-- -->
<h2 th:if="${param.status}" th:text="'저장 완료'"></h2>
...
- th:if 해당 조건이 참일 때
- ${param.status} : 파라미터 값을 조회할 수 있는 기
- 참이면 '저장완료' 가 나온다.
상품 실제 등록시 '저장 완료' 메세지를 확인할 수 있다.

'Spring MVC 웹페이지 만들기' 카테고리의 다른 글
Spring MVC | (4) 상품 수정, 리다이렉트 (0) | 2024.04.02 |
---|---|
Spring MVC | (3) 상품 등록, @ModelAttribute 와 @RequestParam 차이점 (0) | 2024.04.01 |
Spring MVC | (2) 상품 상세 , 타임리프 (0) | 2024.03.31 |
Spring MVC | (1) 상품 목록, 뷰 템플릿 , 타임리프 (0) | 2024.03.27 |
Spring MVC | 상품 도메인 개발 (Item, ItemRepository 클래스 및 테스트 코드 작성) (0) | 2024.03.27 |