<BasicItemController>
package hello.itemservice.web.basic;
import hello.itemservice.domain.item.Item;
import hello.itemservice.domain.item.ItemRepository;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
@RequestMapping("/basic/items")
@RequiredArgsConstructor
public class BasicItemController {
private final ItemRepository itemRepository;
// //@Autowired 생성자가 하나 이므로 생략
// public BasicItemController(ItemRepository itemRepository) {
// this.itemRepository = itemRepository;
// }
@GetMapping
public String items(Model model){
List<Item> items = itemRepository.findAll();
model.addAttribute("items",items);
return "basic/items";
}
@PostConstruct
public void init(){
itemRepository.save(new Item("itemA",10000,10));
itemRepository.save(new Item("itemB",20000,20));
}
}
컨트롤러는 itemRepository에서 모든 상품을 조회한 다음에 모델에 담는다.
그 후 뷰 템플릿을 호출한다.
@PostContruct란?
의존성 주입이 완료된 후에 실행되어야 하는 method에 사용
이 클래스에서는 테스트 용 데이터를 추가하는 목적으로 사용
@RequiredArgsConstructor란?
final이 붙은 멤버변수만 사용해서 생성자를 자동으로 만들어준다.
** 생성자가 딱 1개만 있으면 스프링이 해당 생성자에 @Autowired로 의존관계를 주입해준다. 이 때문에 final 키워드를 빼면 안된다.
items.html을 뷰 템플릿 영역으로 복사하고 수정
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<link th:href="@{/css/bootstrap.min.css}"
href="../css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container" style="max-width: 600px">
<div class="py-5 text-center">
<h2>상품 목록</h2>
</div>
<div class="row">
<div class="col">
<button class="btn btn-primary float-end"
onclick="location.href='addForm.html'"
th:onclick="|location.href='@{/basic/items/add}'|"
type="button">상품 등록
</button>
</div>
</div>
<hr class="my-4">
<div>
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>상품명</th>
<th>가격</th>
<th>수량</th>
</tr>
</thead>
<tbody>
<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/${item.id}|}" th:text="${item.itemName}">상품명</a></td>
<td th:text="${item.price}">10000</td>
<td th:text="${item.quantity}">10</td>
</tr>
</tbody>
</table>
</div>
</div> <!-- /container -->
</body>
</html>
타임리프 사용 선언
<html xmlns:th="http://www.thymeleaf.org">
타임리프 뷰 템플릿을 거치게 되면 원래 값을 th:xxx 값으로 변경한다. 만약 값이 없다면 새로 생성한다.
**** th:xxx 가 붙은 부분은 서버사이드에서 랜더링 되고, 기존 것을 대체한다.
단. HTML을 파일로 직접 열었을 때, th:xxx가 있어도 웹 브라우저는 th:속성을 알지 못하므로 무시한다.
<link th:href="@{/css/bootstrap.min.css}"
href="../css/bootstrap.min.css" rel="stylesheet">
타임리프의 URL 링크 표현식 --> @{...}
th:href="@{/css/bootstrap.min.css}"
리터럴 대체 ==> |...|
반복 출력 ==> 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/${item.id}|}" th:text="${item.itemName}">상품명</a></td>
<td th:text="${item.price}">10000</td>
<td th:text="${item.quantity}">10</td>
</tr>
th: each문을 통해 모델에 포함된 item 컬렉션 데이터가 item 변수에 하나씩 포함되고, 반복문 안에서 item 변수를 사용할 수 있다.
변수 표현식 ==> ${...}
<td th:text="${item.price}">10000</td>
모델에 포함된 값이나 타임리프 변수로 선언한 값을 조회할 수 있다.
내용 변경 ==> th:text
<td th:text="${item.price}">10000</td>
내용의 값을 th:text 의 값으로 변경한다.
여기서는 10000을 ${item.price} 의 값으로 변경한다.
'BackEnd > spring' 카테고리의 다른 글
간단한 Web페이지 프로젝트(6) - PRG Post/Redirect/Get (0) | 2024.07.07 |
---|---|
간단한 Web페이지 프로젝트(5) - 상품 수정 (0) | 2024.07.06 |
간단한 Web페이지 프로젝트(4)- 상품등록 처리-@ModelAttribute (0) | 2024.07.06 |
간단한 Web페이지 프로젝트(3)- 상품 상세 (0) | 2024.07.05 |
간단한 Web페이지 프로젝트(1)-상품 도메인 개발 (0) | 2024.07.03 |