1. Thymeleaf를 사용하는 프로젝트 생성
- 스프링 부트에서는 기본적으로 JSP 대신에 Thymeleaf나 FreeMarker, Mustache 등을 이용해서 화면을 처리함.
- 프로젝트 생성시 Thymeleaf 의존성 추가
- Thymeleaf는 기본적으로 templates 폴더를 기본으로 사용함.
Thymeleaf 코드 예시
1
2
3
4
5
6
7
8
9
10
| <!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1 th:text="${'Hello World'}"></h1>
</body>
</html>
|
- 기본적인 사용 방법은 기존의 속성 앞에 `‘th:’를 붙여주고 속성값을 지정하는 것.
- JSP와 달리 별도의 태그를 이용하지 않고 HTML을 그대로 유지한 상태에서 필요한 동작이나 값을 추가하는 방식임.
2. Thymeleaf의 기본 사용법
1
2
3
4
5
6
7
8
9
| @Data //Getter/Setter, toString(), equals(), hashCode() 자동 생성
@Builder(toBuilder = true)
public class SampleDTO {
private Long sno;
private String first;
private String last;
private LocalDateTime regTime;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| @Controller
@RequestMapping("/sample")
@Log4j2
public class SampleController {
@GetMapping("/ex1")
public void ex1() {
log.info("ex1...........");
}
@GetMapping({"/ex2"})
public void exModel(Model model) {
List<SampleDTO> list = IntStream.rangeClosed(1,20).asLongStream().mapToObj(i -> {
SampleDTO dto = SampleDTO.builder()
.sno(i)
.first("First.."+i)
.last("Last.."+i)
.regTime(LocalDateTime.now())
.build();
return dto;
}).collect(Collectors.toList());
model.addAttribute("list", list);
}
}
|
SampleDTO
타입의 객체를 20개 추가하고 이를 Model에 담아서 전송.
3. 반복문 처리
1) 기본 코드
th:each = "변수 : ${목록}"
1
2
3
4
5
6
7
| <ul>
<li th:each="dto : ${list}">
<!-- [[]] : 인라인 표현식.
별도의 태그 속성으로 지정하지 않고 사용하고자 할 때 유용 -->
[[${dto}]]
</li>
</ul>
|
2) 반복문의 상태(state) 객체
* 상태변수 종류
- index : 0부터 시작하는 인덱스
- count : 1부터 시작하는 인덱스
- size : 리스트에 저장된 요소의 개수
- even : 현재 반복이 짝수인지 확인. true/false 반환
- odd : 현재 반복이 홀수인지 확인. true/false 반환
- first : 현재 반복이 첫번째인지 확인. true/false 반환
- last : 현재 반복이 마지막인지 확인. true/false 반환
1
2
3
| <li th:each="dto, state : ${list}">
[[${state.index}]] --- [[${dto}]]
</li>
|
4. 제어문 처리
1) th:if ~ th:unless
↓ sno의 값이 5의 배수인 것들만 출력
1
2
3
| <li th:each="dto, state : ${list}" th:if="${dto.sno % 5 == 0}">
[[${dto}]]
</li>
|
↓ sno가 5로 나눈 나머지가 0인 경우에는 sno
만을 출력하고(if)
↓ 그렇지 않다면(unless) first
를 출력
1
2
3
4
| <li th:each="dto, state : ${list}">
<span th:if="${dto.sno % 5 == 0}" th:text="${'-----------------------' + dto.sno}"></span>
<span th:unless="${dto.sno % 5 == 0}" th:text="${dto.first}"></span>
</li>
|
2) 삼항연산자
↓ Thymeleaf는 특이하게도 단순 if와 같이 2개의 항만으로도 처리할 수 있음.
1
| <li th:each="dto, state : ${list}" th:text="${dto.sno % 5 == 0} ? ${dto.sno}"></li>
|
↓ sno
가 5로 나눈 나머지가 0인 경우 sno
만을 출력, 나머지는 first
출력.
1
| <li th:each="dto, state : ${list}" th:text="${dto.sno % 5 == 0} ? ${dto.sno} : ${dto.first}"></li>
|
↓ sno
를 5로 나눈 나머지가 0인 경우에만 특정한 css를 적용.
1
2
3
4
5
6
7
8
9
| <style>
.target {
background-color: red;
}
</style>
<ul>
<li th:each="dto, state : ${list}" th:class="${dto.sno % 5 == 0} ? 'target'" th:text="${dto}"></li>
</ul>
|
5. inline 속성
- inline 속성은 주로 자바스크립트 처리에서 유용함.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| @GetMapping({"/exInline"})
public String exInline(RedirectAttributes redirectAttributes) {
log.info("exInline................");
SampleDTO dto = SampleDTO.builder()
.sno(100L)
.first("First...100")
.last("Last...100")
.regTime(LocalDateTime.now())
.build();
redirectAttributes.addFlashAttribute("result", "success");
redirectAttributes.addFlashAttribute("dto", dto);
return "redirect:/sample/ex3";
}
@GetMapping("/ex3")
public void ex3() {
log.info("ex3");
}
|
1
2
3
4
5
6
7
8
9
| <body>
<h1 th:text="${result}"></h1>
<h1 th:text="${dto}"></h1>
<script th:inline="javascript">
var msg = [[${result}]];
var dto = [[${dto}]];
</script>
</body>
|
/sample/exInline
⇒ 자바스크립트 부분을 살펴보면 별도의 처리를 안했음에도 불구하고 문자열은 자동으로 ““이 추가되어 문자열이 되는 것을 볼 수 있고, 같이 전송된 dto는 JSON 포맷의 문자열이 된 것을 볼 수 있음.
th:block
- 별도의 태그가 필요하지 않음.
th:block
은 실제 화면에서는 html로 처리되지 않음.
⇒ 아래와 같이 루프 등을 별도로 처리하는 용도로 많이 사용함.
1
2
3
| <th:block th:each="dto : ${list}">
<li th:text="${dto.sno % 5 == 0} ? ${dto.sno} : ${dto.first}"></li>
</th:block>
|
6. 링크 처리
@{}
를 이용해서 사용.SampleController
의 exModel()
메서드 수정
⇒ @GetMapping()
에는 배열을 이용해 하나 이상의 URL을 처리할 수 있음.
1
2
3
4
| @GetMapping({"/ex2", "/exLink"})
public void exModel(Model model) {
...
}
|
1) 링크에 파라미터 추가
1
2
3
4
5
| <ul>
<li th:each="dto : ${list}">
<a th:href="@{/sample/exView(sno=${dto.sno})}">[[${dto}]]</a>
</li>
</ul>
|
2) sno
를 path로 이용하기
1
2
3
| <li th:each="dto : ${list}">
<a th:href="@{/sample/exView/{sno}(sno = ${dto.sno})}">[[${dto}]]</a>
</li>
|