스프링 mvc1 - 웹 페이지 만들기

2023. 1. 25. 19:00spring/mvc

1/25

 

*모든 내용을 기록하지 않을 것임.

 

* 낯설거나 기억해야될 내용 위주로 기록

 

* Controller 기본틀

@Controller
@RequestMapping("/basic/items")
@RequiredArgsConstructor
public class BasicItemController {

    private final ItemRepository itemRepository;

 

- @RequestMapping -> url경로

- @RequiredArgsConstructor -> private final ItemRepository itemRepository 를 자동으로

생성자 주입으로 만들어줌

 

 

*  타임리프

 

* 사용 선언

<html xmlns:th="http://www.thymeleaf.org">

 

* URL 링크 표현식 (@{....}

<link th:href="@{/css/bootstrap.min.css}"
        href="../css/bootstrap.min.css" rel="stylesheet">

-  뷰 템플릿을 거치게 되면 기존 .../css .............을 덮어쓰고

/css/bootstrap.min.css 가 나온다.

 

 

* 속성 변경 (th:onclick)

onclick="location.href='addForm.html'"
th:onclick="|location.href='@{/basic/items/add}'|"
type="button">상품 등록</button>

- 기존 addForm.html로 가던 경로를 타임리프 경로로 바꾼다.

- 리터럴 대체 (|...|)

  ---> 문자와 표현식은 분리되어 있어서 원래는 더해서 사용해야 하는데 리터럴 대체 문법으로는 편하게 가능하다.

<td><a href="item.html" th:href="@{/basic/items/{itemId}(itemId=${item.id})}" th:text="${item.id}"> 회원id</a></td>
<td><a href="item.html" th:href="@{/basic/items/{itemId}(itemId=${item.id})}" th:text="${item.itemName}">상품명</a></td>

 

* 반복 출력 (th:each)

<tr th:each="item : ${items}">
  <td><a href="item.html" th:href="@{/basic/items/{itemId}(itemId=${item.id})}" th:text="${item.id}"> 회원id</a></td>
  <td><a href="item.html" th:href="@{/basic/items/{itemId}(itemId=${item.id})}" th:text="${item.itemName}">상품명</a></td>
  <td th:text="${item.price}">10000</td>
  <td th:text="${item.quantity}">10</td>
</tr>

- 모델 items 에서 item을 하나씩 빼오는 기능 (for문이랑 비슷함)

- th:href="@{/basic/items/{.....}(items=${item.id})}" 경로 지정

- th:hext="${item.id}" 표시될 텍스트 지정

 

* 상품 등록 

@GetMapping("/add")
@PostMapping("/add")

- 같은 URL을 사용하지만 http 메서드로 구분해준다.

- @GetMapping 은 상품 등록 폼을 가져와주기만 하는 역할

- @PostMapping 은 실제 폼에서 데이터를 가져와 등록해주는 역할

 

* Post 메서드로 받은 폼 데이터를 등록하는 로직

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";
}
@PostMapping("/add")
public String addItemV2(@ModelAttribute("item") Item item){

    itemRepository.save(item);
    return "basic/item";
}

 

- @RequestParam 으로 하나하나 받아서 Item 객체를 생성해서 model에 Item 객체 보내기

- @ModelAttribute 가 위의 모든 기능을 수행해준다.

    (Item 객체 생성 후 setter 메서드 부르기 , Model에 생성한 Item 객체 넘기기)

 

*  수정 (=등록과 같은 원리)

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

- 수정 폼에서 실제 수정 로직 수정

 

* PRG (Post/Redirect/Get)

- redirect: 문법 -> 컨트롤러 호출

 

 

- redirect 없이 뷰를 렌더링하게 되면 <새로고침 했을 때> 계속해서 edit를 수행하게 된다.

 

return "basic/item";
return "redirect:/basic/items/" + item.getId();

 

- BUT 자동으로 인코딩이 안돼서 바로 item.getId() 와 같은 호출은 위험할 수 있다.

 

그러므로

 

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

- RedirectAttributes 사용해서 쓰자

- 치환이 되지 않는건 쿼리 파라미터로 넘어간다. ex) ?status = true

- URL 인코딩 자동으로 해준다.

 

 

'spring > mvc' 카테고리의 다른 글

스프링 mvc1 - 스프링 mvc 구조  (0) 2023.01.22
스프링 mvc1 - MVC 프레임워크 만들기  (0) 2023.01.20