가공한 데이터를 이용하여 화면을 만드는 방법입니다.
화면을 동적으로 만들려면 템플릿 엔진을 사용해야 합니다. 미리 정의된 템플릿(Template)을 만들고 동적으로 HTML페이지를 만들어서 클라이언트에 전달하는 방식입니다. 요청이 올 때마다 서버에서 새로운 HTML 페이지를 만들어 주기 때문에 서버 사이드 렌더링 방식이라고 합니다.
서버 사이드 템플릿 엔진으로는 Thymeleaf,JSP,Freemarker,Groovy,Mustache 등 있습니다.
어떤 것을 사용해도 만들 수 있지만 스프링에서 권장하는 Thymeleaf를 사용을 많이 합니다.
Thymeleaf의 가장 큰 장점은 natural templates 입니다
Thymeleaf를 사용할 때 Thymeleaf 문법을 포함하고 있는 html 파일을 서버 사이드 렌더링을 하지 않고 브라우저에 띄어도
정상적인 화면을 볼 수 있습니다. Thymeleaf의 확장자명은.html이며 ,Thymeleaf의 문법은 html태그 안쪽에 속성으로 사용됩니다.
Thymeleaf 문법
대부분의 html 속성을 th:xxx 로 변경할 수 있습니다.
ex: th:text="${변수명}"
표현 | 설명 | 예제 |
@{ ... } | URL 링크 표현식 | th:href="@{/css/bootstrap.min.css}" th:href="@{/{itemId}/edit(itemId=${item.id})}" |
| ... | | 리터럴 대체 | th:text="|Hi ${user.name}!|" (= th:text="'Hi '+${user.name}+'!'" |
${ ... } | 변수 | th:text=${user.name} |
th:each | 반복 출력 | <tr th:each="item: ${items}"> <td th:text="${item.price}">100</td> </tr> |
th:if th:unless |
조건문 | <tr th:if="${status.even}" th:text="짝수"></td> <td th:unless= "${status.even}" th:text="홀수"> </td> |
th:switch th:case |
조건문과 같다. | <td th:switch="${status.even}"> <span th:case=true>짝수</span> <span th:case=false>홀수</span> |
th:href | 링크 |
<a th:href="@{/thymeleaf/ex01}">
예제1 페이지 이동</a> |
*{ ... } | 선택 변수 | <tr th:object="${items}"> <td th:text="*{price}">100</td> </tr> |
#{ ... } | 메시지. properties 같은 외부 자원에서 코드에 해당하는 문자열 get. | th:text="#{member.register}" |
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p th:text="${data}">Hello Thymeleaf!!</p>
</body>
</html>
@Controller
@RequestMapping(value="/thymeleaf")
public class ThymeleafExController {
@GetMapping(value = "/ex01")
public String thymeleafExample01(Model model) {
model.addAttribute("data", "타임리프 예제 입니다.");
return "thymeleafEx/thymeleafEx01";
}
1.클라이언트의 요청에 대해서 어떤 컨트롤러가 처리할지는 @RequestMapping+@GetMapping 어노테이션으로 url에
"/thymeleaf" 경로로 오는 요청을 ThymeleafExController 가 처리하도록 합니다.
2.model 객체를 이용해 뷰에 전달한 데이터를 key,value 구조로 넣어줍니다.
3.templates 폴더를 기준으로 뷰의 위치와 이름(thymeleafEx01)을 반환합니다.
th:text 예제 심화
dto 패키지를 생성 후 뷰 영역에서 사용할 ItemDto 클래스를 생성합니다. 데이터를 주고받을 때는 Entity 클래스 자체를 반환하면 안 되고 데이터 전달용 객체(Data Transfer Object) 를 생성해서 사용해야 합니다.
데이터베이스의 설계를 외부에 노출할 필요도 없으며, 요청과 응답 객체가 항상 엔티티와 같지 않기 때문입니다.
Getter
@Setter
public class ItemDto {
private Long id;
private String itemNm;
private Integer price;
private String itemDetail;
private String sellStatCd;
private LocalDateTime regTime;
private LocalDateTime updateTime;
}
Controller
@GetMapping(value = "/ex02")
public String thymeleafExample02(Model model) {
ItemDto itemDto = new ItemDto();
itemDto.setItemDetail("상품 상세 설명");
itemDto.setItemNm("테스트 상품1");
itemDto.setPrice(10000);
itemDto.setRegTime(LocalDateTime.now());
model.addAttribute("itemDto", itemDto);
return "thymeleafEx/thymeleafEx02";
}
HTML
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>상품 데이터 출력 예제</h1>
<div>
상품명 : <span th:text="${itemDto.itemNm}"></span>
</div>
<div>
상품상세설명 : <span th:text="${itemDto.itemDetail}"></span>
</div>
<div>
상품등록일 : <span th:text="${itemDto.regTime}"></span>
</div>
<div>
상품가격 : <span th:text="${itemDto.price}"></span>
</div>
</body>
</html>
th:each 예제
위 표와 같이 타임리프 반복문 입니다.
@GetMapping(value = "/ex03")
public String thymeleafExample03(Model model) {
List<ItemDto> itemDtoList = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
ItemDto itemDto = new ItemDto();
itemDto.setItemDetail("상품 상세 설명" + i);
itemDto.setItemNm("테스트 상품" + i);
itemDto.setPrice(1000 * i);
itemDto.setRegTime(LocalDateTime.now());
itemDtoList.add(itemDto);
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>상품 리스트 출력 예제</h1>
<table border="1">
<thead>
<tr>
<td>순번</td>
<td>상품명</td>
<td>상품설명</td>
<td>가격</td>
<td>상품등록일</td>
</tr>
</thead>
<tbody>
<tr th:each="itemDto, status: ${itemDtoList}">
<td th:text="${status.index}"></td>
<td th:text="${itemDto.itemNm}"></td>
<td th:text="${itemDto.itemDetail}"></td>
<td th:text="${itemDto.price}"></td>
<td th:text="${itemDto.regTime}"></td>
</tr>
</tbody>
</table>
</body>
</html>
th:if ,th:unless 예제
조건문 입니다.
@GetMapping(value = "/ex04")
public String thymeleafExample04(Model model) {
List<ItemDto> itemDtoList = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
ItemDto itemDto = new ItemDto();
itemDto.setItemDetail("상품 상세 설명");
itemDto.setItemNm("테스트 상품" + i);
itemDto.setPrice(1000 * i);
itemDto.setRegTime(LocalDateTime.now());
itemDtoList.add(itemDto);
}
model.addAttribute("itemDtoList", itemDtoList);
return "thymeleafEx/thymeleafEx04";
status에는 현재 반복문에 대한 정보가 존재합니다. 인덱스가 짝수일 경우 status.even은 true가 됩니다. 즉 현재 인덱스가 짝수라면 순번에 '짝수'를 출력해줍니다.
현재 인덱스가 짝수가 아닐 경우 즉,홀수일 경우 순번에'홀수'를 출력해줍니다.
<table border="1">
<thead>
<tr>
<td>순번</td>
<td>상품명</td>
<td>상품설명</td>
<td>가격</td>
<td>상품등록일</td>
</tr>
</thead>
<tbody>
<tr th:each="itemDto, status: ${itemDtoList}">
<td th:switch="${status.even}">
<span th:case=true>짝수</span>
<span th:case=false>홀수</span>
</td>
<td th:text="${itemDto.itemNm}"></td>
<td th:text="${itemDto.itemDetail}"></td>
<td th:text="${itemDto.price}"></td>
<td th:text="${itemDto.regTime}"></td>
</tr>
</tbody>
</table>
th:href 예제
@GetMapping(value = "/ex05")
public String thymeleafExample05() {
return "thymeleafEx/thymeleafEx05";
}
<h1>Thymeleaf 링크처리 예제 페이지</h1>
<div>
<a th:href="@{/thymeleaf/ex01}">예제1 페이지 이동</a>
</div>
<div>
<a th:href="@{https://www.thymeleaf.org/}">thymeleaf 공식 페이지 이동</a>
</div>
<div>
<a th:href="@{/thymeleaf/ex06(param1 = '파라미터 데이터1',
param2 = '파라미터 데이터2')}">thymeleaf 파라미터 전달 </a>
</div>
파라미터 값을 전달해야 하는 경우도 처리 가능합니다.
@GetMapping(value = "/ex06")
public String thymeleafExample06(String param1, String param2, Model model) {
model.addAttribute("param1", param1);
model.addAttribute("param2", param2);
return "thymeleafEx/thymeleafEx06";
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1> 파라미터 전달 예제</h1>
<div th:text="${param1}"></div>
<div th:text="${param2}"></div>
</body>
</html>
보통 웹사이트를 만들려면 header,footer,menu 등 공통적인 페이지 구성 요소들이 있습니다.
이런 영역들을 각가의 페이지마다 같은 소스코드를 넣는다면 변경이 일어날 때마다 이를 포함하고
있는 모든 페이지를 수정해야 할 것입니다. Thymeleaf 의 페이지 레이아웃 기능을 사용한다면 공통 요소 관리를
쉽게 관리 할 수 있습니다.
'HTML+JavaScript' 카테고리의 다른 글
flutter 공식문서 예제 들고오기 (0) | 2024.06.18 |
---|---|
Bootstrap (0) | 2023.03.03 |