프로그래밍/spring boot

[스프링부트] 실전! 스프링 부트와 JPA 활용1 #7 웹 계층 개발(3)

aSpring 2023. 11. 12. 19:47
728x90
728x90
※ 본 포스팅은 김영한 강사님의 인프런 '실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발' 강의를 들으며 작성한 수강일지 입니다.

 

 

 

| 웹 계층 개발

1. 홈 화면과 레이아웃
2. 회원 등록
3. 회원 목록 조회
4. 상품 등록
5. 상품 목록
6. 상품 수정
7. 변경 감지와 병합(merge)
8. 상품 주문
9. 주문 목록으로 검색, 취소
10. 다음으로

 

6. 상품 수정

 

상품 수정 컨트롤러

ItemUpdateController

@GetMapping("items/{itemId}/edit")
public String updateItemForm(@PathVariable("itemId") Long itemId, Model model) {
    Book item = (Book) itemService.findOne(itemId);

    BookForm form = new BookForm();
    form.setId(item.getId());
    form.setName(item.getName());
    form.setPrice(item.getPrice());
    form.setStockQuantity(item.getStockQuantity());
    form.setAuthor(item.getAuthor());
    form.setIsbn(item.getIsbn());

    model.addAttribute("form", form);
    return "items/updateItemForm";
}

 

items/updateItemForm.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="fragments/header :: header" />
<body>
<div class="container">
    <div th:replace="fragments/bodyHeader :: bodyHeader"/>
    <form th:object="${form}" method="post">
        <!-- id -->
        <input type="hidden" th:field="*{id}" />
        <div class="form-group">
            <label th:for="name">상품명</label>
            <input type="text" th:field="*{name}" class="form-control"
                   placeholder="이름을 입력하세요" />
        </div>
        <div class="form-group">
            <label th:for="price">가격</label>
            <input type="number" th:field="*{price}" class="form-control"
                   placeholder="가격을 입력하세요" />
        </div>
        <div class="form-group">
            <label th:for="stockQuantity">수량</label>
            <input type="number" th:field="*{stockQuantity}" class="form-
control" placeholder="수량을 입력하세요" />
        </div>
        <div class="form-group">
            <label th:for="author">저자</label>
            <input type="text" th:field="*{author}" class="form-control"
                   placeholder="저자를 입력하세요" />
        </div>
        <div class="form-group">
            <label th:for="isbn">ISBN</label>
            <input type="text" th:field="*{isbn}" class="form-control"
                   placeholder="ISBN을 입력하세요" />
        </div>
        <button type="submit" class="btn btn-primary">Submit</button>
    </form>
    <div th:replace="fragments/footer :: footer" />
</div> <!-- /container -->
</body>
</html>

상품 수정 폼 이동

1. 수정 버튼을 선택하면 /items/{itemId}/edit URL을 GET 방식으로 요청

2. 그 결과로 updateItemForm() 메서드를 실행하는데 이 메서드는 itemService.findOne(itemId) 를 호출해서 수정할 상품을 조회

3. 조회 결과를 모델 객체에 담아서 뷰( items/updateItemForm )에 전달

@PostMapping("items/{itemId}/edit")
public String updateItem(@PathVariable String itemId, @ModelAttribute("form") BookForm form) {

    Book book = new Book();
    book.setId(form.getId());
    book.setName(form.getName());
    book.setPrice(form.getPrice());
    book.setStockQuantity(form.getStockQuantity());
    book.setAuthor(form.getAuthor());
    book.setIsbn(form.getIsbn());

    itemService.saveItem(book);
    return "return:/items";
}

상품 수정 실행

상품 수정 폼 HTML에는 상품의 id(hidden), 상품명, 가격, 수량 정보 있음

1. 상품 수정 폼에서 정보를 수정하고 Submit 버튼을 선택

2. /items/{itemId}/edit URL을 POST 방식으로 요청하고 updateItem() 메서드를 실행

3. 이때 컨트롤러에 파라미터로 넘어온 item 엔티티 인스턴스는 현재 준영속 상태다. 따라서 영속성 컨텍스트 의 지원을 받을 수 없고 데이터를 수정해도 변경 감지 기능은 동작X

@PostMapping("items/{itemId}/edit")
public String updateItem(@PathVariable String itemId, @ModelAttribute("form") BookForm form) {

    Book book = new Book();
    book.setId(form.getId());
    book.setName(form.getName());
    book.setPrice(form.getPrice());
    book.setStockQuantity(form.getStockQuantity());
    book.setAuthor(form.getAuthor());
    book.setIsbn(form.getIsbn());

    itemService.saveItem(book);
    return "redirect:/items";
}

 

- 임의로 id를 조작할 수 없도록 만들어야 함

- 앞/뒷 단에서 user가 item에 대해 권한이 있는지 check하는 로직이 있어야 함

- update를 session에 담아서 처리하는 방법도 있으나 요즘에는 session을 잘 사용하지 않음

 

728x90
728x90