Search
Duplicate

Thymeleaf

Thymeleaf (ํƒ€์ž„๋ฆฌํ”„)

ํƒ€์ž„๋ฆฌํ”„๋Š” ์„œ๋ฒ„ ์‚ฌ์ด๋“œ Java ํ…œํ”Œ๋ฆฟ ์—”์ง„์ž…๋‹ˆ๋‹ค. HTML, XML, JavaScript, CSS ๋“ฑ์˜ ๋งˆํฌ์—… ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋™์  ์›น ํŽ˜์ด์ง€๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ํƒ€์ž„๋ฆฌํ”„๋Š” ๊ฐ„๋‹จํ•˜๊ณ  ์ง๊ด€์ ์ธ ๊ตฌ๋ฌธ์„ ์ œ๊ณตํ•˜๋ฉฐ, Spring Framework์™€์˜ ํ†ตํ•ฉ์ด ์šฉ์ดํ•ฉ๋‹ˆ๋‹ค.
Spring Framework ์—์„œ์˜ ํ…œํ”Œ๋ฆฟ ์—”์ง„์œผ๋กœ ์‚ฌ์šฉํ•˜๋˜ JSP ๋ฐ JSP ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ธฐ๋Šฅ๋“ค์„ ๋ชจ๋‘ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ๋Š” ํ…œํ”Œ๋ฆฟ ์—”์ง„์ด๋‹ค.

ํ…œํ”Œ๋ฆฟ ์—”์ง„์ด๋ž€?

ํ…œํ”Œ๋ฆฟ ์—”์ง„์€ ๋™์  ์›น ํŽ˜์ด์ง€๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ํ…œํ”Œ๋ฆฟ ์—”์ง„์€ ๋ฏธ๋ฆฌ ์ •์˜๋œ ํ…œํ”Œ๋ฆฟ๊ณผ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ์ตœ์ข…์ ์œผ๋กœ ์›น ํŽ˜์ด์ง€๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ฐœ๋ฐœ์ž๋Š” ๋™์ผํ•œ ํ…œํ”Œ๋ฆฟ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋™์ ์œผ๋กœ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ…œํ”Œ๋ฆฟ ์—”์ง„์€ ์ฃผ๋กœ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ์—์„œ ์‹คํ–‰๋˜๋ฉฐ, ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์™„์„ฑ๋œ HTML์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

ํƒ€์ž„๋ฆฌํ”„ ์ฃผ์š” ๊ธฐ๋Šฅ

โ€ข
๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ: ํƒ€์ž„๋ฆฌํ”„๋Š” ์„œ๋ฒ„ ์‚ฌ์ด๋“œ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ํ…œํ”Œ๋ฆฟ์— ๋ฐ”์ธ๋”ฉํ•˜์—ฌ ๋™์ ์œผ๋กœ ์›น ํŽ˜์ด์ง€๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
โ€ข
์กฐ๊ฑด๋ฌธ๊ณผ ๋ฐ˜๋ณต๋ฌธ: ํƒ€์ž„๋ฆฌํ”„๋Š” if๋ฌธ๊ณผ ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ…œํ”Œ๋ฆฟ์—์„œ ๋ณต์žกํ•œ ๋กœ์ง์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
โ€ข
๊ตญ์ œํ™” ์ง€์›: ํƒ€์ž„๋ฆฌํ”„๋Š” ๋‹ค๊ตญ์–ด ์ง€์›์„ ์œ„ํ•œ ๊ตญ์ œํ™” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์—ฌ ๋‹ค์–‘ํ•œ ์–ธ์–ด๋กœ ์›น ํŽ˜์ด์ง€๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํƒ€์ž„๋ฆฌํ”„ ๋ฌธ๋ฒ•

โ€ข
ํƒ€์ž„๋ฆฌํ”„ ๋ธ”๋ก
โ—ฆ
th:block
โ€ข
ํƒ€์ž„๋ฆฌํ”„ ์ถœ๋ ฅ
โ—ฆ
th:text
โ—ฆ
th:html
โ—ฆ
th:href
โ€ข
ํƒ€์ž„๋ฆฌํ”„ ์ œ์–ด๋ฌธ
โ—ฆ
์กฐ๊ฑด๋ฌธ
โ–ช
th:if
โ–ช
th:switch
โ—ฆ
๋ฐ˜๋ณต๋ฌธ
โ–ช
th:each
โ€ข
th:object
โ€ข
form
โ€ข
th:with
โ€ข
ํƒ€์ž„๋ฆฌํ”„ ์„ธ์…˜ ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ
โ€ข
ํƒ€์ž„๋ฆฌํ”„ ์ž๋ฐ” ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ

ํƒ€์ž„๋ฆฌํ”„ ๋ธ”๋ก

ํƒ€์ž„๋ฆฌํ”„ <th:block>

ํƒ€์ž„๋ฆฌํ”„ th:block์€ ํƒ€์ž„๋ฆฌํ”„์˜ ๋ธ”๋ก ํƒœ๊ทธ๋กœ, HTML ์š”์†Œ๋ฅผ ๊ทธ๋ฃนํ™”ํ•˜๊ณ  ์กฐ๊ฑด๋ฌธ, ๋ฐ˜๋ณต๋ฌธ ๋“ฑ์„ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. th:block ํƒœ๊ทธ ๋‚ด๋ถ€์˜ ์š”์†Œ๋“ค์€ ๋…๋ฆฝ์ ์ธ ๋ธ”๋ก์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๋ฉฐ, ํƒ€์ž„๋ฆฌํ”„ ํ‘œํ˜„์‹๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ ๋™์ ์ธ ์›น ํŽ˜์ด์ง€๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
<th:block> ... </th:block>
HTML
๋ณต์‚ฌ

ํƒ€์ž„๋ฆฌํ”„ ์ถœ๋ ฅ

ํƒ€์ž„๋ฆฌํ”„ th:text

ํƒ€์ž„๋ฆฌํ”„ th:text๋Š” ํƒœ๊ทธ ๋‚ด๋ถ€์˜ ํ…์ŠคํŠธ๋ฅผ ๋™์ ์œผ๋กœ ์„ค์ •ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„์—์„œ ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ์›น ํŽ˜์ด์ง€์— ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
<th:block th:text="${data}"></th:block>
HTML
๋ณต์‚ฌ
์œ„์˜ ์˜ˆ์‹œ์—์„œ๋Š” data ๋ณ€์ˆ˜์˜ ๊ฐ’์„ ํ•ด๋‹น ํƒœ๊ทธ์˜ ํ…์ŠคํŠธ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

ํƒ€์ž„๋ฆฌํ”„ th:html

ํƒ€์ž„๋ฆฌํ”„ th:html์€ HTML ์š”์†Œ ์•ˆ์— HTML ์ฝ”๋“œ๋ฅผ ๋™์ ์œผ๋กœ ์„ค์ •ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„์—์„œ ์ƒ์„ฑ๋œ HTML์„ ์›น ํŽ˜์ด์ง€์— ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
<th:block th:html="${htmlData}"></th:block>
HTML
๋ณต์‚ฌ
์œ„์˜ ์˜ˆ์‹œ์—์„œ๋Š” htmlData ๋ณ€์ˆ˜์— ์ €์žฅ๋œ HTML ์ฝ”๋“œ๋ฅผ ํ•ด๋‹น ํƒœ๊ทธ ์•ˆ์— ๋™์ ์œผ๋กœ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.

ํƒ€์ž„๋ฆฌํ”„ th:href

ํƒ€์ž„๋ฆฌํ”„ th:href๋Š” HTML ์š”์†Œ์˜ href ์†์„ฑ์„ ๋™์ ์œผ๋กœ ์„ค์ •ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„์—์„œ ์ƒ์„ฑ๋œ ๋งํฌ๋ฅผ ์›น ํŽ˜์ด์ง€์— ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
<a th:href="@{/path/to/page}">Link</a>
HTML
๋ณต์‚ฌ
์œ„์˜ ์˜ˆ์‹œ์—์„œ๋Š” "/path/to/page" ๊ฒฝ๋กœ๋กœ ์ด๋™ํ•˜๋Š” ๋งํฌ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
<a th:href="@{/path/to/page( param1=${value1}, param2=${value2} )">Link</a>
HTML
๋ณต์‚ฌ
์œ„์™€ ๊ฐ™์ด th:href ์†์„ฑ์œผ๋กœ @{ } ๊ธฐํ˜ธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด,
(ํŒŒ๋ผ๋ฏธํ„ฐ1=๊ฐ’1, ํŒŒ๋ผ๋ฏธํ„ฐ2=๊ฐ’2) ํ˜•์‹์œผ๋กœ ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๋‹ค.
ex) param1: 10, param2 : 20
<a th:href="/path/to/page?param1=10&param2=20">Link</a>
HTML
๋ณต์‚ฌ

th:href="@{}"์™€ href="" ์ฐจ์ด

th:href="@{}"๋Š” ํƒ€์ž„๋ฆฌํ”„์˜ ๋งํฌ ํ‘œํ˜„์‹์œผ๋กœ, ํƒ€์ž„๋ฆฌํ”„๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋™์ ์œผ๋กœ ๋งํฌ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด href=""๋Š” ์ •์ ์ธ ๋ฐฉ์‹์œผ๋กœ ๋งํฌ๋ฅผ ์ง€์ •ํ•˜๋Š” HTML ์†์„ฑ์ž…๋‹ˆ๋‹ค.
โ€ข
th:href="@{}" ์˜ˆ์‹œ: <a th:href="@{/path/to/page}">Link</a>
โ€ข
href="" ์˜ˆ์‹œ: <a href="/path/to/page">Link</a>
ํƒ€์ž„๋ฆฌํ”„์˜ th:href๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฒฝ๋กœ์™€ ์ƒ๋Œ€๊ฒฝ๋กœ๋ฅผ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋ฏ€๋กœ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด๋ถ€์—์„œ ์ด๋™ํ•˜๋Š” ๋งํฌ๋ฅผ ํŽธ๋ฆฌํ•˜๊ฒŒ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํƒ€์ž„๋ฆฌํ”„ ์ œ์–ด๋ฌธ

์กฐ๊ฑด๋ฌธ

โ€ข
<th:if>
โ€ข
<th:switch>

ํƒ€์ž„๋ฆฌํ”„ <th:if>

ํƒ€์ž„๋ฆฌํ”„ th:if๋Š” ์กฐ๊ฑด๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ…œํ”Œ๋ฆฟ์—์„œ ํŠน์ • ๋ถ€๋ถ„์„ ์กฐ๊ฑด์— ๋”ฐ๋ผ ๋ณด์—ฌ์ฃผ๊ฑฐ๋‚˜ ์ˆจ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์กฐ๊ฑด๋ฌธ์€ ํƒ€์ž„๋ฆฌํ”„ ํ‘œํ˜„์‹์œผ๋กœ ์ž‘์„ฑ๋˜๋ฉฐ, ํ•ด๋‹น ์กฐ๊ฑด์ด ์ฐธ์ผ ๋•Œ๋งŒ ํ•ด๋‹น ์š”์†Œ๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
<th:block th:if="${condition}"> ... </th:block>
HTML
๋ณต์‚ฌ
์œ„์˜ ์˜ˆ์‹œ์—์„œ๋Š” condition์ด ์ฐธ์ผ ๋•Œ์—๋งŒ ํ•ด๋‹น ์š”์†Œ๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

th:if ์กฐ๊ฑด๋ฌธ ์˜ˆ์‹œ

1.
boolean ํƒ€์ž…์˜ ์กฐ๊ฑด์‹
2.
๊ฐ’ ๋น„๊ต
3.
๊ฐ์ฒด์˜ ๋ณ€์ˆ˜ ๋น„๊ต
4.
๋ฌธ์ž์—ด ๋น„๊ต

boolean ํƒ€์ž…์˜ ์กฐ๊ฑด์‹

boolean checked = true; // ๋˜๋Š” false
Java
๋ณต์‚ฌ
<th:block th:if="${checked}"> <h1>checked ์กฐ๊ฑด์ด true ์ผ๋•Œ</h1> </th:block>
HTML
๋ณต์‚ฌ

๊ฐ’ ๋น„๊ต

int age = 20;
Java
๋ณต์‚ฌ
<th:if="${ age >= 20 }"> <h1>age >= 20 ์กฐ๊ฑด์ด ๋งŒ์กฑํ•  ๋•Œ</h1> </th:if>
HTML
๋ณต์‚ฌ

๊ฐ์ฒด์˜ ๋ณ€์ˆ˜ ๋น„๊ต

public class Person { String name = "ALOHA"; int age = 20; }
Java
๋ณต์‚ฌ
<th:if="${ person.age >= 20 }"> <h1>age >= 20 ์กฐ๊ฑด์ด ๋งŒ์กฑํ•  ๋•Œ</h1> </th:if>
HTML
๋ณต์‚ฌ

๋ฌธ์ž์—ด ๋น„๊ต

public class Person { String name = "ALOHA"; int age = 20; }
Java
๋ณต์‚ฌ
๋ฌธ์ž์—ด ๋น„๊ต๋„ == ๊ธฐํ˜ธ๋กœ ๋น„๊ต๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.
<th:if="${ person.name == 'ALOHA' }"> <h1>age >= 20 ์กฐ๊ฑด์ด ๋งŒ์กฑํ•  ๋•Œ</h1> </th:if>
HTML
๋ณต์‚ฌ
#strings ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ equlas() ํ•จ์ˆ˜๋ฅผ ๋น„๊ตํ•  ์ˆ˜ ์žˆ๋‹ค.
#strings.equals( ๋ฌธ์ž์—ด1, ๋ฌธ์ž์—ด2 )
<th:block th:if="${ person != null && #strings.equals( person.name, 'ALOHA' ) }"> <h1 th:text="${ person.name }"></h1> </th:block>
HTML
๋ณต์‚ฌ
๋ฌธ์ž์—ด ๋“ฑ ๊ฐ์ฒด์˜ ๋ณ€์ˆ˜ ๋น„๊ต ์‹œ, ๊ฐ์ฒด๊ฐ€ null ์ธ์ง€ ์ฒดํฌํ•˜๋Š” ๊ฒƒ์ด ์œ ์˜ํ•œ๋‹ค.
<th:block th:if="${ person != null and person.name == 'ALOHA' }"> <h1 th:text="${ person.name }"></h1> </th:block>
HTML
๋ณต์‚ฌ
AND ์—ฐ์‚ฐ์„ and ๋˜๋Š” && ๋กœ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
<th:block th:if="${ person != null && #strings.equals( person.name, 'ALOHA' ) }"> <h1 th:text="${ person.name }"></h1> </th:block>
HTML
๋ณต์‚ฌ
์‚ผํ•ญ ์—ฐ์‚ฐ์ž๋ฅผ ์ด์šฉํ•˜์—ฌ null ์ฒดํฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค.
<h1 th:text="${ person == null ? '์ด๋ฆ„์—†์Œ' : person.name }"></h1>
HTML
๋ณต์‚ฌ

ํƒ€์ž„๋ฆฌํ”„ <th:switch>

ํƒ€์ž„๋ฆฌํ”„ th:switch๋Š” switch๋ฌธ๊ณผ ๋น„์Šทํ•œ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ํ…œํ”Œ๋ฆฟ์—์„œ ๋‹ค์–‘ํ•œ ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๋™์ž‘์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ๊ฒฝ์šฐ๋Š” ํƒ€์ž„๋ฆฌํ”„ th:case ํƒœ๊ทธ๋กœ ์ •์˜๋˜๋ฉฐ, ์กฐ๊ฑด์— ๋”ฐ๋ผ ํ•ด๋‹น ๊ฒฝ์šฐ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
<th:block th:switch="${variable}"> <th:case="value1">...</th:case> <th:case="value2">...</th:case> <th:case="value3">...</th:case> ... </th:block>
HTML
๋ณต์‚ฌ
์œ„์˜ ์˜ˆ์‹œ์—์„œ๋Š” variable์˜ ๊ฐ’์— ๋”ฐ๋ผ ํ•ด๋‹นํ•˜๋Š” ๊ฒฝ์šฐ์˜ ์ฝ”๋“œ ๋ธ”๋ก์ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

๋ฐ˜๋ณต๋ฌธ

ํƒ€์ž„๋ฆฌํ”„ <th:each>

ํƒ€์ž„๋ฆฌํ”„ th:each๋Š” ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ…œํ”Œ๋ฆฟ์—์„œ ๋™์ผํ•œ ์š”์†Œ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ณต๋ฌธ์€ ํƒ€์ž„๋ฆฌํ”„ ํ‘œํ˜„์‹์œผ๋กœ ์ž‘์„ฑ๋˜๋ฉฐ, ์ง€์ •๋œ ๋ฐ์ดํ„ฐ ์ปฌ๋ ‰์…˜์˜ ๊ฐ ํ•ญ๋ชฉ์— ๋Œ€ํ•ด ๋ฐ˜๋ณตํ•˜์—ฌ ์š”์†Œ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
<th:block th:each="item : ${items}"> ... </th:block>
HTML
๋ณต์‚ฌ
์œ„์˜ ์˜ˆ์‹œ์—์„œ๋Š” items ์ปฌ๋ ‰์…˜์˜ ๊ฐ ํ•ญ๋ชฉ์— ๋Œ€ํ•ด ํ•ด๋‹น ์š”์†Œ๊ฐ€ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
items ์— ๋ฐฐ์—ด ๋˜๋Š” ์ปฌ๋ ‰์…˜์„ ์ง€์ •ํ•˜์—ฌ ์ „์ฒด ๋ฐ˜๋ณต์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1.
๊ธฐ๋ณธ ๋ฐ˜๋ณต๋ฌธ
2.
๋ฐ˜๋ณต ๊ฐ์ฒด ์†์„ฑ
3.
ํ•„ํ„ฐ๋ง ์กฐ๊ฑด
4.
์ค‘์ฒฉ ๋ฐ˜๋ณต๋ฌธ
5.
isEmtpy()

๊ธฐ๋ณธ ๋ฐ˜๋ณต๋ฌธ

<th:block th:each="์š”์†Œ, iterStat : ${๋ฐฐ์—ด or ์ปฌ๋ ‰์…˜}"> <th:block th:text="${ ์š”์†Œ }"></th:block> <th:block th:text="${ ์š”์†Œ.๋ณ€์ˆ˜ }"></th:block> </th:block>
HTML
๋ณต์‚ฌ
iterStat : ๋ฐ˜๋ณต ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด์„œ index, count ๋“ฑ ์ˆœ์„œ ๋ฒˆํ˜ธ์™€ ์—ฌ๋Ÿฌ ํ•„ํ„ฐ๋ง ์กฐ๊ฑด๊ฐ’์„ ์‚ฌ์šฉ

๋ฐ˜๋ณต ๊ฐ์ฒด ์†์„ฑ

์†์„ฑ
์„ค๋ช…
iterStat.index
0๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋Š” ์ธ๋ฑ์Šค
iterStat.count
1๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋Š” ์ˆœ๋ฒˆ
iterStat.size
์ปฌ๋ ‰์…˜์˜ ์ด ํฌ๊ธฐ
iterStat.even
ํ˜„์žฌ ์ธ๋ฑ์Šค๊ฐ€ ์ง์ˆ˜์ธ์ง€ (true ๋˜๋Š” false)
iterStat.odd
ํ˜„์žฌ ์ธ๋ฑ์Šค๊ฐ€ ํ™€์ˆ˜์ธ์ง€ (true ๋˜๋Š” false)
iterStat.first
์ฒซ ๋ฒˆ์งธ ์š”์†Œ์ธ์ง€ (true ๋˜๋Š” false)
iterStat.last
๋งˆ์ง€๋ง‰ ์š”์†Œ์ธ์ง€ (true ๋˜๋Š” false)
<th:block th:each="item, iterStat : ${items}"> index : <th:block th:text=${iterStat.index}></th:block> count: <th:block th:text=${iterStat.count}></th:block> size: <th:block th:text=${iterStat.size}></th:block> ... </th:block>
HTML
๋ณต์‚ฌ

ํ•„ํ„ฐ๋ง ์กฐ๊ฑด

<th:block th:each="์š”์†Œ, iterStat : ${๋ฐฐ์—ด or ์ปฌ๋ ‰์…˜}" th:if="${ ์กฐ๊ฑด }"> <th:block th:text="${ ์š”์†Œ }"></th:block> <th:block th:text="${ ์š”์†Œ.๋ณ€์ˆ˜ }"></th:block> </th:block>
HTML
๋ณต์‚ฌ
th:each ๋ฐ˜๋ณต ์•ˆ์—์„œ, th:if="${ ์กฐ๊ฑด }" ์กฐ๊ฑด์— ๋งŒ์กฑํ•˜๋Š” ์š”์†Œ๋งŒ ํ•„ํ„ฐ๋งํ•˜์—ฌ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ๋‹ค.

์ค‘์ฒฉ ๋ฐ˜๋ณต๋ฌธ

public class Users { public String username; public String password; public String name; public List<UserAuth> authList; }
Java
๋ณต์‚ฌ
public class UserAuth { public String username; public String auth; }
Java
๋ณต์‚ฌ
List<Users> userList;
Java
๋ณต์‚ฌ
<th:block th:each="user, iterStat : ${userList}"> <th:block th:text="${user.name}"></th:block> ... <th:block th:each="auth, iterStat : ${user.authList}"> <th:block th:text="${auth.username}"></th:block> <th:block th:text="${auth.auth}"></th:block> ... </th:block> </th:block>
HTML
๋ณต์‚ฌ

isEmtpy()

์ง€์ •ํ•œ ์ปฌ๋ ‰์…˜์ด ๋น„์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฉ”์†Œ๋“œ
<th:block th:if="${ ์ปฌ๋ ‰์…˜.isEmpty()}"> </th:block>
HTML
๋ณต์‚ฌ
<th:block th:if=" #lists.isEmpty( ์ปฌ๋ ‰์…˜ ) "> </th:block>
HTML
๋ณต์‚ฌ

th:classappend=โ€${ ์กฐ๊ฑด ? โ€˜์†์„ฑ1โ€™ : โ€˜์†์„ฑ2โ€™ }โ€

<th:block th:each=" item, iterStat : ${items}" > <tr class="row" th:classappend="${ iterStat.odd ? 'odd' : 'even' }"> <td><th:block th:text="${iterStat.index}"></th:block></td> <td><th:block th:text="${iterStat.count}"></th:block></td> <td><th:block th:text="${iterStat.size}"></th:block></td> <td><th:block th:text="${item}"></th:block></td> <td><th:block th:text="${iterStat.odd}"></th:block></td> <td><th:block th:text="${iterStat.even}"></th:block></td> <td><th:block th:text="${iterStat.first}"></th:block></td> <td><th:block th:text="${iterStat.last}"></th:block></td> </tr> </th:block>
HTML
๋ณต์‚ฌ
th:classappend=โ€™โ€™ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ๊ฒฝ์šฐ์— ํด๋ž˜์Šค ์†์„ฑ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

ํƒ€์ž„๋ฆฌํ”„ th:object

ํƒ€์ž„๋ฆฌํ”„์˜ th:object๋Š” ํผ ์ฒ˜๋ฆฌ๋ฅผ ๊ฐ„์†Œํ™”ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์ค‘์š”ํ•œ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์ด ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด ํผ๊ณผ ๊ด€๋ จ๋œ ๊ฐ์ฒด๋ฅผ ์ง€์ •ํ•˜์—ฌ ํ•ด๋‹น ๊ฐ์ฒด์˜ ์†์„ฑ์— ์‰ฝ๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฃผ์š” ํŠน์ง•:

โ€ข
๊ฐ์ฒด ๋ฐ”์ธ๋”ฉ: th:object๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํผ์— ๊ฐ์ฒด๋ฅผ ๋ฐ”์ธ๋”ฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํผ ํ•„๋“œ์™€ ๊ฐ์ฒด ์†์„ฑ์„ ์‰ฝ๊ฒŒ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
โ€ข
*{...} ๋ฌธ๋ฒ•: th:object์™€ ํ•จ๊ป˜ *{...} ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ”์ธ๋”ฉ๋œ ๊ฐ์ฒด์˜ ์†์„ฑ์— ์ง์ ‘ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
โ€ข
์ฝ”๋“œ ๊ฐ„์†Œํ™”: ๋ฐ˜๋ณต์ ์ธ ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ์ค„์—ฌ ์ฝ”๋“œ๋ฅผ ๋” ๊ฐ„๊ฒฐํ•˜๊ณ  ์ฝ๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
th:object="${๊ฐ์ฒด}โ€
์ƒ์œ„ ํƒœ๊ทธ์—์„œ ๊ฐ์ฒด๋ฅผ ๋“ฑ๋กํ•˜๊ณ , ํ•˜์œ„ ํƒœ๊ทธ์—์„œ *{๋ณ€์ˆ˜} ํ˜•ํƒœ๋กœ ์ ‘๊ทผ ๊ฐ€๋Šฅ
<div th:object="${user}"> <ul> <li th:text="*{no}"></li> <li th:text="*{id}"></li> <li th:text="*{username}"></li> <li th:text="*{password}"></li> <li th:text="*{name}"></li> <li th:text="*{ #dates.format( createdAt, 'yyyy-MM-dd HH:mm:ss' ) }"></li> <li th:text="*{ #dates.format( updatedAt, 'yyyy-MM-dd HH:mm:ss' ) }"></li> </ul> </div>
HTML
๋ณต์‚ฌ

ํƒ€์ž„๋ฆฌํ”„ form

th:field="*{๋ณ€์ˆ˜}" id, name, value ์†์„ฑ์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑ
<form action="" method="post" th:object="${user}"> <input type="text" th:field="*{no}"> <br> <input type="text" th:field="*{id}"> <br> <input type="text" th:field="*{username}"> <br> <input type="text" th:field="*{password}"> <br> <input type="text" th:field="*{name}"> <br> </form>
HTML
๋ณต์‚ฌ
์œ„์™€๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ์‹ค์ œ๋กœ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋žœ๋”๋ง๋œ๋‹ค.
<form action="" method="post"> <input type="text" id="no" name="no" value="1"> <br> <input type="text" id="id" name="id" value="c8f3ed9e-b16e-4d94-9c5c-1eaf1e5b17f1"> <br> <input type="text" id="username" name="username" value="ALOHA"> <br> <input type="text" id="password" name="password" value="123456"> <br> <input type="text" id="name" name="name" value="์•Œ๋กœํ•˜"> <br> </form>
HTML
๋ณต์‚ฌ
๋ผ๋””์˜ค ๋ฒ„ํŠผ (input type=โ€radioโ€) ์ฒดํฌํ•˜๊ธฐ
<form action="" method="post" th:object="${user}"> ... <input type="radio" id="male" value="๋‚จ์ž" name="gender" th:checked="*{ gender == '๋‚จ์ž' }"> <label for="male">๋‚จ์ž</label> <input type="radio" id="female" value="์—ฌ์ž" name="gender" th:checked="*{ gender == '์—ฌ์ž' }"> <label for="female">์—ฌ์ž</label> ... </form>
HTML
๋ณต์‚ฌ
์„ ํƒ ์ƒ์ž (select) ์ฒดํฌํ•˜๊ธฐ
select ์— th:field="*{type}" ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, type ๊ฐ’๊ณผ ์ผ์น˜ํ•˜๋Š” option ์„ ์ž๋™์œผ๋กœ ์„ ํƒ
<form action="" method="post" th:object="${user}"> ... <select th:field="*{type}"> <option value="์‚ฌ์šฉ์ž ํƒ€์ž…" disabled>์‚ฌ์šฉ์ž ํƒ€์ž…</option> <option value="์‚ฌ์šฉ์ž">์‚ฌ์šฉ์ž</option> <option value="๊ด€๋ฆฌ์ž">๊ด€๋ฆฌ์ž</option> </select> ... </form>
HTML
๋ณต์‚ฌ
th:selected=โ€${ ์กฐ๊ฑด }โ€, th:selected=โ€*{ ์กฐ๊ฑด }โ€ ํ˜•ํƒœ๋กœ selected ์—ฌ๋ถ€๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ๋„ ์žˆ์Œ
<form action="" method="post" th:object="${user}"> ... <select name="type"> <option value="์„ ํƒ์•ˆํ•จ" th:selected="*{ type == null }">์„ ํƒ์•ˆํ•จ</option> <option value="์‚ฌ์šฉ์ž" th:selected="*{ type == '์‚ฌ์šฉ์ž' }">์‚ฌ์šฉ์ž</option> <option value="๊ด€๋ฆฌ์ž" th:selected="*{ type == '๊ด€๋ฆฌ์ž' }">๊ด€๋ฆฌ์ž</option> </select> ... </form>
HTML
๋ณต์‚ฌ
๋‚ ์งœ (input type=โ€dateโ€) ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ’์„ ์ง€์ •ํ•˜๊ธฐ โ€˜yyyy-MM-ddโ€™ ํฌ๋งท์„ ๊ฐ’์„ ์ง€์ •ํ•ด์ฃผ๋ฉด ๋“ค์–ด๊ฐ„๋‹ค
<form action="" method="post" th:object="${user}"> ... <input type="date" th:value="*{ #dates.format( createdAt, 'yyyy-MM-dd' ) }" id="createdAt" name="createdAt"> <br> <input type="date" th:value="*{ #dates.format( updatedAt, 'yyyy-MM-dd' ) }" id="updatedAt" name="updatedAt"> <br> ... </form>
HTML
๋ณต์‚ฌ

ํƒ€์ž„๋ฆฌํ”„ th:with

th:with๋Š” ํ…œํ”Œ๋ฆฟ ๋‚ด์—์„œ ์ง€์—ญ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์†์„ฑ์ž…๋‹ˆ๋‹ค. ๋ณต์žกํ•œ ํ‘œํ˜„์‹์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๋“ค๊ฑฐ๋‚˜ ๋ฐ˜๋ณต์ ์ธ ๊ณ„์‚ฐ์„ ์ค„์ผ ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์š” ํŠน์ง•:

โ€ข
์ง€์—ญ ๋ณ€์ˆ˜ ์„ ์–ธ: th:with๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ํƒœ๊ทธ ๋ฒ”์œ„ ๋‚ด์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
โ€ข
๋ณต์žกํ•œ ํ‘œํ˜„์‹ ๊ฐ„์†Œํ™”: ๊ธด ํ‘œํ˜„์‹์„ ๋ณ€์ˆ˜์— ์ €์žฅํ•˜์—ฌ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
โ€ข
์„ฑ๋Šฅ ์ตœ์ ํ™”: ๋™์ผํ•œ ํ‘œํ˜„์‹์„ ์—ฌ๋Ÿฌ ๋ฒˆ ๊ณ„์‚ฐํ•˜๋Š” ๋Œ€์‹  ํ•œ ๋ฒˆ๋งŒ ๊ณ„์‚ฐํ•˜์—ฌ ๋ณ€์ˆ˜์— ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
th:with="๋ณ€์ˆ˜๋ช…=${ํ‘œํ˜„์‹}"
์—ฌ๋Ÿฌ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•  ๋•Œ๋Š” ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค: th:with="๋ณ€์ˆ˜1=${ํ‘œํ˜„์‹1}, ๋ณ€์ˆ˜2=${ํ‘œํ˜„์‹2}"

๊ธฐ๋ณธ ์‚ฌ์šฉ ์˜ˆ์ œ:

<div th:with="userName=${user.name}"> <p th:text="|์•ˆ๋…•ํ•˜์„ธ์š”, ${userName}๋‹˜!|"></p> <p th:text="|${userName}๋‹˜์˜ ์ •๋ณด์ž…๋‹ˆ๋‹ค.|"></p> </div>
HTML
๋ณต์‚ฌ

์—ฌ๋Ÿฌ ๋ณ€์ˆ˜ ์„ ์–ธ:

<div th:with="firstName=${user.name}, lastName=${user.surname}"> <p th:text="|์ด๋ฆ„: ${firstName} ${lastName}|"></p> </div>
HTML
๋ณต์‚ฌ

๋ณต์žกํ•œ ๊ณ„์‚ฐ ๊ฐ„์†Œํ™”:

<div th:with="totalPrice=${product.price * product.quantity}, discount=${totalPrice * 0.1}, finalPrice=${totalPrice - discount}"> <p>์ƒํ’ˆ ๊ฐ€๊ฒฉ: <span th:text="${totalPrice}"></span>์›</p> <p>ํ• ์ธ ๊ธˆ์•ก: <span th:text="${discount}"></span>์›</p> <p>์ตœ์ข… ๊ฐ€๊ฒฉ: <span th:text="${finalPrice}"></span>์›</p> </div>
HTML
๋ณต์‚ฌ

๋ฐ˜๋ณต๋ฌธ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉ:

<tr th:each="user : ${userList}" th:with="isAdmin=${user.type == '๊ด€๋ฆฌ์ž'}"> <td th:text="${user.name}"></td> <td th:text="${isAdmin} ? '๊ด€๋ฆฌ์ž' : '์ผ๋ฐ˜ ์‚ฌ์šฉ์ž'"></td> <td> <span th:if="${isAdmin}" class="badge">ADMIN</span> </td> </tr>
HTML
๋ณต์‚ฌ
th:with๋กœ ์„ ์–ธ๋œ ๋ณ€์ˆ˜๋Š” ํ•ด๋‹น ํƒœ๊ทธ์™€ ๊ทธ ํ•˜์œ„ ํƒœ๊ทธ์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํƒ€์ž„๋ฆฌํ”„ ์„ธ์…˜ ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ

// ๋กœ๊ทธ์ธ ์œ ์ € Users loginUser = new Uers(); loginUser.setNo(1L); loginUser.setId( UUID.randomUUID().toString() ); loginUser.setUsername("ALOHA"); loginUser.setPassword("123456"); loginUser.setName("์˜ค์Šน์›"); loginUser.setGender("์—ฌ์ž"); // ๋‚จ์ž ์—ฌ์ž loginUser.setType("๊ด€๋ฆฌ์ž"); // ์‚ฌ์šฉ์ž ๊ด€๋ฆฌ์ž loginUser.setCreatedAt(new Date()); loginUser.setUpdatedAt(new Date()); loginUser.setAuthList(authList); session.setAttribute("loginUser", loginUser); model.addAttribute("loginUser", loginUser);
Java
๋ณต์‚ฌ
@Data @NoArgsConstructor @AllArgsConstructor @Builder public class Users { private Long no; private String id; private String username; private String password; private String name; private String gender; private String type; private Date createdAt; private Date updatedAt; List<UserAuth> authList; // ์‚ฌ์šฉ์ž ๊ถŒํ•œ ํ™•์ธ ๋ฉ”์†Œ๋“œ public boolean containsAuth(String auth) { for (UserAuth userAuth : authList) { if (userAuth.getAuth().equals(auth)) { return true; } } return false; } }
Java
๋ณต์‚ฌ
<!-- ์„ธ์…˜ ๊ฐ€์ ธ์˜ค๊ธฐ --> <h2>${session.loginUser}</h2> <h3 th:text="${session.loginUser.name}"></h3> <h3 th:text="${session.loginUser.username}"></h3> <h3 th:text="${session.loginUser.password}"></h3>
HTML
๋ณต์‚ฌ

ํƒ€์ž„๋ฆฌํ”„ ์ž๋ฐ” ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ

// ๊ถŒํ•œ UserAuth roleUser = UserAuth.builder().auth("ROLE_USER").build(); UserAuth roleAdmin = UserAuth.builder().auth("ROLE_ADMIN").build(); List<UserAuth> authList = List.of( roleUser, roleAdmin ); // ๋กœ๊ทธ์ธ ์œ ์ € Users loginUser = new Uers(); loginUser.setNo(1L); loginUser.setId( UUID.randomUUID().toString() ); loginUser.setUsername("ALOHA"); loginUser.setPassword("123456"); loginUser.setName("์˜ค์Šน์›"); loginUser.setGender("์—ฌ์ž"); // ๋‚จ์ž ์—ฌ์ž loginUser.setType("๊ด€๋ฆฌ์ž"); // ์‚ฌ์šฉ์ž ๊ด€๋ฆฌ์ž loginUser.setCreatedAt(new Date()); loginUser.setUpdatedAt(new Date()); loginUser.setAuthList(authList);
Java
๋ณต์‚ฌ
@Data @NoArgsConstructor @AllArgsConstructor @Builder public class Users { private Long no; private String id; private String username; private String password; private String name; private String gender; private String type; private Date createdAt; private Date updatedAt; List<UserAuth> authList; // ์‚ฌ์šฉ์ž ๊ถŒํ•œ ํ™•์ธ ๋ฉ”์†Œ๋“œ public boolean containsAuth(String auth) { for (UserAuth userAuth : authList) { if (userAuth.getAuth().equals(auth)) { return true; } } return false; } }
Java
๋ณต์‚ฌ
@Data @Builder public class UserAuth { private String username; private String auth; }
Java
๋ณต์‚ฌ
... <input type="checkbox" name="authList" id="role_user" th:checked="${ loginUser.containsAuth('ROLE_USER') }"> <label for="role_user">ROLE_USER</label> <input type="checkbox" name="authList" id="role_admin" th:checked="${ loginUser.containsAuth('ROLE_ADMIN') }"> <label for="role_admin">ROLE_ADMIN</label> <br>
HTML
๋ณต์‚ฌ
Users ๊ฐ์ฒด์˜ containsAuth() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ ํŠน์ • ๊ถŒํ•œ (โ€™ROLE_USERโ€™, โ€˜ROLE_ADMINโ€™) ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•ด๋ด…๋‹ˆ๋‹ค.