[Spring] PRG Post/Redirect/Get

이지현·2023년 9월 18일
0

Spring

목록 보기
7/7
post-thumbnail
번호목차
1.상품 등록 폼
2.Redirect
3.RedirectAttributes

1. 상품 등록 폼

상품 등록 폼은 다음 방식으로 서버에 데이터를 전달함

  • POST - HTML Form
  • content-type: application/x-www-form-urlencoded
  • 메시지 바디에 쿼리 파리미터 형식으로 전달(itemName=itemA&price=10000&quantity=10) - ex) 회원 가입, 상품 주문, HTML Form 사용

상품 등록 처리 - @RequestParam

  • itemName 요청 파라미터 데이터를 해당 변수에 받음
  • Item 객체를 생성하고 itemRepository를 통해서 저장함
  • 저장된 item을 모델에 담아서 뷰에 전달함
@PostMapping("/add")
public String addItemV1(@RequestParam String itemName,
                        @RequestParam int price,
                        @RequestParam Integer quantity,
                        Model model) {
                        
      Item item = new Item();
      item.setItemName(itemName);
      item.setPrice(price);
      item.setQuantity(quantity);
      itemRepository.save(item);
      model.addAttribute("item", item);
      
      return "basic/item";
  }

상품 등록 처리 - @ModelAttribute

  • @ModelAttribute를 사용해서 한번에 처리
  • Item 객체 생성 후 요청 파라미터의 값을 프로퍼티 접근법으로 입력해줌
  • 지정한 객체를 자동으로 넣어줌
@PostMapping("/add")
public String addItemV2(@ModelAttribute("item") Item item) {
	itemRepository.save(item); 
    //model.addAttribute("item", item); //자동 추가, 생략 가능
    
    return "basic/item";
  }

상품 등록 처리 - ModelAttribute 이름 생략

  • 생략 시 model에 저장되는 name은 클래스명 첫글자만 소문자로 등록 Item -> item
@PostMapping("/add")
public String addItemV3(@ModelAttribute Item item) {
	itemRepository.save(item);
    return "basic/item";
}

상품 등록 처리 - ModelAttribute 전체 생략

/**
* @ModelAttribute 자체 생략 가능
* model.addAttribute(item) 자동 추가 */

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

2. Redirect

상품 수정 처리

@PostMapping("/{itemId}/edit")
public String edit(@PathVariable Long itemId, @ModelAttribute Item item) { 	   itemRepository.update(itemId, item);
	return "redirect:/basic/items/{itemId}";
}
  • 상품 등록 폼에서 데이터를 입력하고 저장을 선택하면 POST /add + 상품 데이터를 서버로 전송gka
  • 이 상태에서 새로 고침을 또 선택하면 마지막에 전송한 POST /add + 상품 데이터를 서버로 다시 전송함
    -> 내용은 같고, ID만 다른 상품 데이터가 계속 쌓이게 됨

해결 방법

  • 상품 저장 후 뷰 템플릿으로 이동하는 것이 아닌 상품 상세 화면으로 리다이렉트를 호출해주면 됨
  • 웹 브라우저는 리다이렉트의 영향으로 상품 저장 후에 실제 상품 상세 화면으로 다시 이동함
    -> 마지막에 호출한 내용이 상품 상세 화면인 GET /items/{id}가 되는 것임
@PostMapping("/add")
public String addItemV5(Item item) {
	itemRepository.save(item);
    return "redirect:/basic/items/" + item.getId();
}

이런 문제 해결 방식을 PRG Post/Redirect/Get라 함

3. RedirectAttributes

  • "redirect:/basic/items/" + item.getId() redirect에서 +item.getId()처럼 URL에 변수를 더해서 사용하는 것은 URL 인코딩이 안되기 때문에 위험함
  • 리다이렉트 할 때 간단히 status=true 추가, 뷰 템플릿에서 이 값이 있으면 "저장되었습니다." 메시지 출력
@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}";
}

자료 출처

profile
2022.08 ~ 2023.09 / 현재 티스토리 이전 : https://jihyun-devstory.tistory.com/

0개의 댓글