# Thymeleaf ๊ธฐ๋Šฅ - ๊ธฐ๋ณธ
Study Repository

Thymeleaf ๊ธฐ๋Šฅ - ๊ธฐ๋ณธ

by rlaehddnd0422

ํƒ€์ž„๋ฆฌํ”„ ์†Œ๊ฐœ

ํƒ€์ž„๋ฆฌํ”„ ํŠน์ง•

  • SSR - ์„œ๋ฒ„ ์‚ฌ์ด๋“œ์—์„œ HTML์„ ๋ Œ๋”๋ง ํ•ฉ๋‹ˆ๋‹ค 
  • ๋„ค์ธ„๋Ÿด ํ…œํ”Œ๋ฆฟ
  • ์Šคํ”„๋ง ํ†ตํ•ฉ ์ง€์›

ํƒ€์ž„๋ฆฌํ”„ ๊ธฐ๋ณธ ๊ธฐ๋Šฅ

์„ ์–ธ : ํƒ€์ž„๋ฆฌํ”„๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋‹ค์Œ ์„ ์–ธ์„ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

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

 

๊ธฐ๋ณธ ํ‘œํ˜„์‹ 

ํƒ€์ž„๋ฆฌํ”„๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋ณธ ํ‘œํ˜„์‹๋“ค์„ ์ œ๊ณตํ•œ๋‹ค. ์ง€๊ธˆ๋ถ€ํ„ฐ ํ•˜๋‚˜์”ฉ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

- ๊ฐ„๋‹จํ•œ ํ‘œํ˜„ 

1. ๋ณ€์ˆ˜ ํ‘œํ˜„์‹ : ${...}

2. ์„ ํƒ ๋ณ€์ˆ˜ ํ‘œํ˜„์‹ : *{...}

3. ๋ฉ”์‹œ์ง€ ํ‘œํ˜„์‹ : #{...} / 3. ๊ธฐ๋ณธ ๊ฐ์ฒด๋“ค์—์„œ ์‚ฌ์šฉ

4. ๋งํฌ URL ํ‘œํ˜„์‹ : @{...} / 5. URL ๋งํฌ ๊ธฐ๋Šฅ์—์„œ ์‚ฌ์šฉ

5. ์กฐ๊ฐ ํ‘œํ˜„์‹ : ~{...} / 14. ํ…œํ”Œ๋ฆฟ ์กฐ๊ฐ ๊ธฐ๋Šฅ์—์„œ ์‚ฌ์šฉ

 

- ๋ฆฌํ„ฐ๋Ÿด

1. ํ…์ŠคํŠธ : 'one text', 'Another one!'

2. ์ˆซ์ž : 0, 34, 3.0, 12.3 ..

3. ๋ถ€์šธ : true, false

4. ๋„ : null

5. ๋ฆฌํ„ฐ๋Ÿด ํ† ํฐ : one, sometext, main ...

 

- ๋ฌธ์ž ์—ฐ์‚ฐ

 1. ํ•ฉ์น˜๊ธฐ : +

2. ๋ฆฌํ„ฐ๋Ÿด ๋Œ€์ฒด : |The name is ${name}|

 

- ์‚ฐ์ˆ  ์—ฐ์‚ฐ

1. Binary operators : +, -, *, /, %

2. Minus sign (๋‹จํ•ญ ์—ฐ์‚ฐ): - ex) -1, -2

 

- ๋ถˆ๋ฆฐ ์—ฐ์‚ฐ

1. Binary operators : and, or

2. Boolean negation (๋‹จํ•ญ ์—ฐ์‚ฐ) : !, not

 

- ๋น„๊ต์™€ ๋™๋“ฑ

1. ๋น„๊ต : > (gt) , < (lt) , >=(ge) , <= (le) (gt,lt,ge,le)

2. ๋™๋“ฑ ์—ฐ์‚ฐ : ==(eq), !=(ne)

 

- ์กฐ๊ฑด ์—ฐ์‚ฐ

1. If-then : (if) ? (then)

2. If-then-else : (if) ? (then) : (else)

3. Default : (value) ?: (defaultvalue)

 

- ํŠน๋ณ„ํ•œ ํ† ํฐ

No operation :   _ (๋„์šฐ๊ณ  ๋ฐ‘์ค„)

 

 

์ด์ œ ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์„ ํ•˜๋‚˜์”ฉ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


1. ํ…์ŠคํŠธ - text, utext

ํƒ€์ž„๋ฆฌํ”„๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ HTML ํ…Œ๊ทธ์˜ ์†์„ฑ์— ๊ธฐ๋Šฅ์„ ์ •์˜ํ•ด์„œ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. HTML์˜ ์ฝ˜ํ…์ธ ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅํ•  ๋•Œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด 

th:text๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. 

ex) <span th:text="${data}">HTML ์‚ฌ์ด๋“œ์—์„œ ๋ Œ๋”๋งํ•  ํ…์ŠคํŠธ</span>

 

๋งŒ์•ฝ HTML ํ…Œ๊ทธ์˜ ์†์„ฑ์ด ์•„๋‹Œ HTML ์ปจํ…์ธ  ์˜์—ญ์•ˆ์—์„œ ์ง์ ‘ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅํ•˜๊ณ  ์‹ถ์œผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด [[...]]์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

ex) [[${data}]]

@Controller
@RequestMapping("/basic")
public class BasicController {

    @GetMapping("/text-basic")
    public String textBasic(Model model) {
        model.addAttribute("data", "Hello Spring!");
        return "basic/text-basic";
    }

 

View template : basic/text-basic 

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>์ปจํ…์ธ ์— ๋ฐ์ดํ„ฐ ์ถœ๋ ฅํ•˜๊ธฐ</h1>
<ul>
    <li><span th:text="${data}">CSR ํ…์ŠคํŠธ</span></li>
    <li>์ปจํ…์ธ  ์•ˆ์—์„œ ์ง์ ‘ ์ถœ๋ ฅํ•˜๊ธฐ = [[${data}]]</li>
</ul>
</body>
</html>

 

 

SSR                                                                                                                 CSR

 

CSR(ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง, ์ ˆ๋Œ€ ๊ฒฝ๋กœ๋กœ  HTML ํ˜ธ์ถœ)์—์„œ๋Š” th๊ฐ€ ๋ถ™์€ ์†์„ฑ์„ ์ฝ์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฌด์‹œํ•ฉ๋‹ˆ๋‹ค.

CSR ์†Œ์Šค์ฝ”๋“œ

 

SSR์—์„œ๋Š” th๊ฐ€ ๋ถ™์€ ์†์„ฑ์„ ์ฝ์Šต๋‹ˆ๋‹ค.

 

Escape

HTML ๋ฌธ์„œ๋Š” <, >๊ฐ™์€ ํŠน์ˆ˜ ๋ฌธ์ž๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ •์˜๋ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋ทฐ ํ…œํ”Œ๋ฆฟ์œผ๋กœ HTMLํ™”๋ฉด์„ ์ƒ์„ฑํ•  ๋•Œ๋Š” ์ถœ๋ ฅํ•˜๋Š” ๋ฐ์ดํ„ฐ์— ์ด๋Ÿฌํ•œ ํŠน์ˆ˜๋ฌธ์ž๊ฐ€ ์žˆ๋Š” ๊ฒƒ์„ ์ฃผ์˜ํ•ด์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์•ž์—์„œ ๋งŒ๋“  ์˜ˆ์ œ์˜ ๋ฐ์ดํ„ฐ์ธ "Hello Spring!"์„ "Hello <b>Spring</b>"๋กœ ๋ฐ”๊ฟ”์„œ ์‹คํ–‰ํ•ด๋ณด๋ฉด

 

"Hello Spring!"์„ "Hello <b>Spring</b>"๋กœ ๋ฐ”๊ฟ”์„œ ์‹คํ–‰ํ•œ ๊ฒฐ๊ณผ
์†Œ์Šค์ฝ”๋“œ

<b>ํ…Œ๊ทธ๊ฐ€ &lt;b&gt;๋กœ ๋ณ€๊ฒฝ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์›น ๋ธŒ๋ผ์šฐ์ €๋Š” <๋ฅผ HTML ํƒœ๊ทธ์˜ ์‹œ์ž‘์œผ๋กœ ์ธ์‹ํ•˜๊ธฐ ๋•Œ๋ฌธ์— <๋ฅผ ํ…Œ๊ทธ์˜ ์‹œ์ž‘์ด ์•„๋‹ˆ๋ผ ๋ฌธ์ž๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ(&lt, &gt)์„ HTML ์—”ํ‹ฐํ‹ฐ ๋ผ๊ณ ํ•ฉ๋‹ˆ๋‹ค.

HTML์—์„œ ์‚ฌ์šฉํ•˜๋Š” ํŠน์ˆ˜๋ฌธ์ž(<,>)๋ฅผ HTML์—”ํ‹ฐํ‹ฐ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์„ ์ด์Šค์ผ€์ดํ”„(escape)๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  ํƒ€์ž„๋ฆฌํ”„๊ฐ€ ์ œ๊ณตํ•˜๋Š” th:text, [[...]]๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด์Šค์ผ€์ดํ”„๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

<  โ–ถ๏ธŽ &lt;

<  โ–ถ๏ธŽ &gt;

 

์ด์Šค์ผ€์ดํ”„์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ ค๋ฉด text ๋Œ€์‹  utext๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ [[...]] ๋Œ€์‹  [(...)]์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

@GetMapping("/text-unescaped")
public String textUnescaped(Model model) {
    model.addAttribute("data", "Hello <b>Spring!</b>");
    return "basic/text-unescaped";
}

 

View template : basic/text-unescpaed

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>Unescaped Text</title>
</head>
<body>

<h1>text vs utext</h1>
<ul>
  <li>th:text = <span th:text="${data}"></span></li>
  <li>th:utext = <span th:utext="${data}"></span></li>
</ul>

<h1><span th:inline="none">[[...]] vs [(...)]</span></h1>
<ul>
  <li><span th:inline="none">[[...]] = </span>[[${data}]]</li>
  <li><span th:inline="none">[(...)] = </span>[(${data})]</li>
</ul>
</body>
</html>

 

th:inline = "none" : ํƒ€์ž„๋ฆฌํ”„๋Š” [[...]]์„ ํ•ด์„ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ํ™”๋ฉด [[...]]์„ ๊ธ€์ž๋ฅผ ๋ณด์—ฌ์ค„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด ๋•Œ inline = "none" ์˜ต์…˜์€ ์ด ํƒœ๊ทธ์•ˆ์—์„œ ํƒ€์ž„๋ฆฌํ”„๊ฐ€ ํ•ด์„ํ•˜์ง€ ์•Š๋„๋ก ํ•ด์ฃผ๋Š” ์˜ต์…˜์ž…๋‹ˆ๋‹ค.

 

โ—๏ธ์‹ค์ œ ์„œ๋น„์Šค๋ฅผ ๊ฐœ๋ฐœํ•˜๋‹ค ๋ณด๋ฉด escape๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„์„œ HTML์ด ์ •์ƒ ๋ Œ๋”๋ง ๋˜์ง€ ์•Š๋Š” ์ˆ˜๋งŽ์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

escape๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ํ•˜๊ณ  , ๊ผญ ํ•„์š”ํ•  ๋•Œ๋งŒ unescape๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ํ•ฉ์‹œ๋‹ค.

 


2. ๋ณ€์ˆ˜ - SpringEL

๋ณ€์ˆ˜ ํ‘œํ˜„์‹ ${...} ์—๋Š” ์Šคํ”„๋ง EL์ด๋ผ๋Š” ์Šคํ”„๋ง์ด ์ œ๊ณตํ•˜๋Š” ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

@Data
static class User {
    private String username;
    private int age;

    public User(String username, int age) {
        this.username = username;
        this.age = age;
    }
}

@GetMapping("/variable")
public String variable(Model model) {
    User userA = new User("DongwoongKim", 25);

    List<User> list = new ArrayList<>();
    list.add(userA);

    Map<String, User> map = new HashMap<>();
    map.put("userA", userA);

    model.addAttribute("user", userA);
    model.addAttribute("users", list);
    model.addAttribute("userMap", map);

    return "basic/variable";
}

 

View template - basic/variable

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<h1>SpringEL ํ‘œํ˜„์‹</h1> <ul>Object
  <li>${user.username} = <span th:text="${user.username}"></span></li>
  <li>${user['username']} = <span th:text="${user['username']}"></span></li>
  <li>${user.getUsername()} = <span th:text="${user.getUsername()}"></span></li>
</ul>

<h1>์ง€์—ญ ๋ณ€์ˆ˜ - (th:with)</h1>
<div th:with="first=${users[0]}">
  <p>์ฒ˜์Œ ์‚ฌ๋žŒ์˜ ์ด๋ฆ„์€ <span th:text="${first.username}"></span></p> </div>

<ul>List
  <li>${users[0].username}    = <span th:text="${users[0].username}"></span></li>
  <li>${users[0]['username']} = <span th:text="${users[0]['username']}"></span></li>
  <li>${users[0].getUsername()} = <span th:text="${users[0].getUsername()}"></span></li>
</ul>

<ul>Map
  <li>${userMap['userA'].username} =  <span th:text="${userMap['userA'].username}"></span></li>
  <li>${userMap['userA']['username']} = <span th:text="${userMap['userA']['username']}"></span></li>
  <li>${userMap['userA'].getUsername()} = <span th:text="${userMap['userA'].getUsername()}"></span></li>
</ul>

</body>
</html>

 

th:with๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ง€์—ญ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (์„ ์–ธ ํƒœ๊ทธ ๋‚ด์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ)
ex) <div th:with="first=${user[0]}">
            <p>์ฒ˜์Œ ์‚ฌ๋žŒ์˜ ์ด๋ฆ„์€ <span th:text="${first.username}"><span></p>
      </div>

first๋Š” div ํƒœ๊ทธ ์•ˆ์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ.

 

๋ทฐ ํ…œํ”Œ๋ฆฟ

 

SpringEL ๋‹ค์–‘ํ•œ ํ‘œํ˜„์‹ ์‚ฌ์šฉ

1. Object

  • user.username : user์˜ username์„ ํ”„๋กœํผํ‹ฐ๋กœ ์ ‘๊ทผ (user.getUsername())
  • user['username'] : ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํ”„๋กœํผํ‹ฐ๋กœ ์ ‘๊ทผ
  • user.getUsername() : user์˜ getUsername()์„ ์ง์ ‘ ํ˜ธ์ถœ

2. List

  • users[0].username : List์—์„œ ์ฒซ ๋ฒˆ์งธ ํšŒ์›์„ ์ฐพ๊ณ  username ํ”„๋กœํผํ‹ฐ ์ ‘๊ทผ 
  • users[0]['username'] : ์œ„์™€ ๊ฐ™์Œ
  • users[0].getUsername() : List์—์„œ ์ฒซ ๋ฒˆ์งธ ํšŒ์›์„ ์ฐพ๊ณ  ๋ฉ”์„œ๋“œ ์ง์ ‘ ํ˜ธ์ถœ

 

3. Map

  • userMap['userA'].username : ๋งต์—์„œ userA๋ฅผ ์ฐพ๊ณ  username ํ”„๋กœํผํ‹ฐ ์ ‘๊ทผ
  • userMap['userA']['username'] : ์œ„์™€ ๊ฐ™์Œ
  • userMap['userA'].getUsername() : ๋งต์—์„œ userA๋ฅผ ์ฐพ๊ณ  ๋ฉ”์†Œ๋“œ ์ง์ ‘ํ˜ธ์ถœ

3. ๊ธฐ๋ณธ ๊ฐ์ฒด๋“ค

ํƒ€์ž„๋ฆฌํ”„๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ฐ์ฒด๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

1. ${#request}

2. ${#response}

3. ${#session}

4. ${#servletContext}

5. ${#locale}

 

(1,2,3,4๋Š” ์Šคํ”„๋ง 3.0๋ถ€ํ„ฐ๋Š” ์ œ๊ณตํ•˜์ง€ ์•Š์Œ)

 

๊ทธ๋Ÿฐ๋ฐ #request๋Š” HttpServletRequest ๊ฐ์ฒด๊ฐ€ ๊ทธ๋Œ€๋กœ ์ œ๊ณต๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๋ ค๋ฉด request.getParameter("data")์ฒ˜๋Ÿผ ๋ถˆํŽธํ•˜๊ฒŒ ์ ‘๊ทผํ•ด์•ผ ํ•˜๋Š”๋ฐ ์ด๋Ÿฐ์ ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ํŽธ์˜ ๊ฐ์ฒด๋„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

 

HTTP ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ ์ ‘๊ทผ : param.ํŒŒ๋ผ๋ฏธํ„ฐ์ด๋ฆ„

ex)  "${param.paramData}"

 

HTTP ์„ธ์…˜ ์ ‘๊ทผ : session.์„ธ์…˜์ด๋ฆ„

ex) "${session.sessionData}"

 

์Šคํ”„๋ง ๋นˆ ์ ‘๊ทผ : @

ex) "${@hellobean.hello('Spring!')}"

 

@GetMapping("/basic-objects")
public String basicObjects(HttpSession session)
{
    session.setAttribute("sessionData", "Hello Session!");
    return "basic/basic-objects";
}

@Component("helloBean")
static class HelloBean {
    public String hello(String data) {
        return "Hello " + data;
    }
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>์‹ ๊ธฐ๋ณธ ๊ฐ์ฒด (Expression Basic Objects)</h1> <ul>
    <li>request = <span th:text="${#request}"></span></li>
    <li>response = <span th:text="${#response}"></span></li>
    <li>session = <span th:text="${#session}"></span></li>
    <li>servletContext = <span th:text="${#servletContext}"></span></li>
    <li>locale = <span th:text="${#locale}"></span></li>
</ul>
<h1>ํŽธ์˜ ๊ฐ์ฒด</h1>
<ul>
    <li>Request Parameter = <span th:text="${param.paramData}"></span></li>
    <li>session = <span th:text="${session.sessionData}"></span></li>
    <li>spring bean = <span th:text="${@helloBean.hello('Spring!')}"></span></li>
</ul>
</body>
</html>

 

๋ทฐ ํ…œํ”Œ๋ฆฟ


4. ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ฐ์ฒด์™€ ๋‚ ์งœ

ํƒ€์ž„๋ฆฌํ”„๋Š” ๋ฌธ์ž, ์ˆซ์ž, ๋‚ ์งœ, URI ๋“ฑ์„ ํŽธ๋ฆฌํ•˜๊ฒŒ ๋‹ค๋ฃจ๋Š” ๋‹ค์–‘ํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ฐ์ฒด๋“ค์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

 

ํƒ€์ž„๋ฆฌํ”„ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ฐ์ฒด๋“ค

  • #message : ๋ฉ”์‹œ์ง€, ๊ตญ์ œํ™” ์ฒ˜๋ฆฌ
  • #uris : URI ์ด์Šค์ผ€์ดํ”„ ์ง€์›
  • #dates : java.util.Date ์„œ์‹ ์ง€์›
  • #calendars : java.util.Calendar ์„œ์‹ ์ง€์›
  • #temporals : ์ž๋ฐ”8 ๋‚ ์งœ ์„œ์‹ ์ง€์›
  • #numbers : ์ˆซ์ž ์„œ์‹ ์ง€์›
  • #strings : ๋ฌธ์ž ๊ด€๋ จ ํŽธ์˜ ๊ธฐ๋Šฅ
  • #objects : ๊ฐ์ฒด ๊ด€๋ จ ๊ธฐ๋Šฅ ์ œ๊ณต
  • #bools : boolean ๊ด€๋ จ ๊ธฐ๋Šฅ ์ œ๊ณต
  • #arrays : ๋ฐฐ์—ด ๊ด€๋ จ ๊ธฐ๋Šฅ ์ œ๊ณต
  • #lists , #sets , #maps : ์ปฌ๋ ‰์…˜ ๊ด€๋ จ ๊ธฐ๋Šฅ ์ œ๊ณต
  • #ids : ์•„์ด๋”” ์ฒ˜๋ฆฌ ๊ด€๋ จ ๊ธฐ๋Šฅ ์ œ๊ณต, ๋’ค์—์„œ ์„ค๋ช…

๋Œ€๋žต ์ด๋Ÿฐ๊ฒƒ๋“ค์ด ์žˆ๋‹ค ์ •๋„๋งŒ ์•Œ๊ณ  ์ž์„ธํžˆ ํ•˜๋‚˜ํ•˜๋‚˜ ๋‹ค ์•Œ ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.

๊ทธ๋ƒฅ ํ•„์š”ํ•œ ์ƒํ™ฉ์ด ์žˆ๋‹ค๋ฉด ์ฐพ์•„์„œ ์‚ฌ์šฉํ•ฉ์‹œ๋‹ค.

์‚ฌ์šฉ ์˜ˆ์‹œ๋กœ #temporals๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๊ณ  ๋„˜์–ด๊ฐ€๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@GetMapping("/date")
public String date(Model model) {
    model.addAttribute("localDateTime", LocalDateTime.now());
    return "basic/date";
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>LocalDateTime</h1>
<ul>
    <li>default = <span th:text="${localDateTime}"></span></li>
    <li>yyyy-MM-dd HH:mm:ss = <span th:text="${#temporals.format(localDateTime,
  'yyyy-MM-dd HH:mm:ss')}"></span></li>
</ul>
<h1>LocalDateTime - Utils</h1>
<ul>
    <li>${#temporals.day(localDateTime)} = <span th:text="${#temporals.day(localDateTime)}"></span></li>
    <li>${#temporals.month(localDateTime)} = <span th:text="${#temporals.month(localDateTime)}"></span></li>
    <li>${#temporals.monthName(localDateTime)} = <span th:text="${#temporals.monthName(localDateTime)}"></span></li>
    <li>${#temporals.monthNameShort(localDateTime)} = <span th:text="${#temporals.monthNameShort(localDateTime)}"></span></li>
    <li>${#temporals.year(localDateTime)} = <span th:text="${#temporals.year(localDateTime)}"></span></li>
    <li>${#temporals.dayOfWeek(localDateTime)} = <span th:text="${#temporals.dayOfWeek(localDateTime)}"></span></li>
    <li>${#temporals.dayOfWeekName(localDateTime)} = <span th:text="${#temporals.dayOfWeekName(localDateTime)}"></span></li>
    <li>${#temporals.dayOfWeekNameShort(localDateTime)} = <span th:text="${#temporals.dayOfWeekNameShort(localDateTime)}"></span></li>
    <li>${#temporals.hour(localDateTime)} = <span th:text="${#temporals.hour(localDateTime)}"></span></li>
    <li>${#temporals.minute(localDateTime)} = <span th:text="${#temporals.minute(localDateTime)}"></span></li>
    <li>${#temporals.second(localDateTime)} = <span th:text="${#temporals.second(localDateTime)}"></span></li>
    <li>${#temporals.nanosecond(localDateTime)} = <span th:text="${#temporals.nanosecond(localDateTime)}"></span></li>
</ul>
</body>
</html>
๋ทฐ ํ…œํ”Œ๋ฆฟ

5. URL ๋งํฌ

ํƒ€์ž„๋ฆฌํ”„์—์„œ URL ๋งํฌ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋Š” @{...} ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

@GetMapping("/link")
public String link(Model model)
{
    model.addAttribute("param1","data1");
    model.addAttribute("param2","data2");
    return "basic/link";
}

 

๋ทฐํ…œํ”Œ๋ฆฟ

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>URL ๋งํฌ</h1>
<ul>
    <li><a th:href="@{/hello}">basic url</a></li>
    <li><a th:href="@{/hello(param1=${param1}, param2=${param2})}">hello query
        param</a></li>
    <li><a th:href="@{/hello/{param1}(param1=${param1})}">path variable</a></li>
    <li><a th:href="@{/hello/{param1}(param1=${param1}, param2=${param2})}">path variable + query parameter</a></li>
</ul>
</body>
</html>

 

  • ๋‹จ์ˆœ URL : /hello โ–ถ๏ธŽ @{/hello} 
  • ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ : /hello?param1=data1&param2=data2 โ–ถ๏ธŽ @{/hello/(param1= ${param1}, param2 = ${param2}) }
  • ๊ฒฝ๋กœ ๋ณ€์ˆ˜  : /hello/data1/data2 โ–ถ๏ธŽ @{/hello/{param1}/{param2} ( param1 = ${param1}, param2 = ${param2}) }

 


6. ๋ฆฌํ„ฐ๋Ÿด

๋ฆฌํ„ฐ๋Ÿด์€ ์†Œ์Šค ์ฝ”๋“œ ์ƒ์— ๊ณ ์ •๋œ ๊ฐ’์„ ๋งํ•˜๋Š” ์šฉ์–ด์ž…๋‹ˆ๋‹ค. 

ex) String a = "hello",  int a = 10์—์„œ "hello", 10์€ ๋ฆฌํ„ฐ๋Ÿด

  • ํƒ€์ž„๋ฆฌํ”„์—๋Š” ๋ฌธ์ž, ์ˆซ์ž, ๋ถˆ๋ฆฐ, null ์ด ๋„ค๊ฐ€์ง€ ๋ฆฌํ„ฐ๋Ÿด์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํƒ€์ž„๋ฆฌํ”„์—์„œ๋Š” ๋ฌธ์ž ๋ฆฌํ„ฐ๋Ÿด์€ ํ•ญ์ƒ '๋กœ ๊ฐ์‹ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • ex) <span th:text = "'hello'">
  • ๊ทธ๋Ÿฐ๋ฐ ๋ฌธ์ž๋ฅผ '๋กœ ๊ฐ์‹ธ๋Š” ์ผ์€ ๋งค์šฐ ๊ท€์ฐฎ์€๋ฐ, ๊ณต๋ฐฑ ์—†์ด ์ญ‰ ์ด์–ด์ง„๋‹ค๋ฉด '๋กœ ์•ˆ ๊ฐ์‹ธ์ฃผ์–ด๋„ ๋ฉ๋‹ˆ๋‹ค. 
  • ๋” ํŽธํ•œ ๋ฐฉ๋ฒ•์€ ๋ฆฌํ„ฐ๋Ÿด ๋Œ€์ฒด ๋ฌธ๋ฒ•์ธ |์„ ์‚ฌ์šฉํ•ด์„œ |...|๋กœ ๊ฐ์‹ธ์ฃผ๋Š” ๋ฐฉ๋ฒ•
@GetMapping("/literal")
public String literal(Model model)
{
    model.addAttribute("data","Spring!");
    return "basic/literal";
}

 

๋ทฐํ…œํ”Œ๋ฆฟ

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body> <h1>๋ฆฌํ„ฐ๋Ÿด</h1>
<ul>
    <!--    <li>"hello world!" = <span th:text="hello world!"></span></li>-->
    <li>'hello' + ' world!' = <span th:text="'hello' + ' world!'"></span></li>
    <li>'hello world!' = <span th:text="'hello world!'"></span></li>
    <li>'hello ' + ${data} = <span th:text="'hello ' + ${data}"></span></li>
    <li> TEST </li> 
    <li>๋ฆฌํ„ฐ๋Ÿด ๋Œ€์ฒด |hello ${data}| = <span th:text="|hello ${data}|"></span></li>
</ul>
</body>
</html>

์ฃผ์„ ์ฝ”๋“œ : ์˜ค๋ฅ˜ ๋ฐœ์ƒ / "hello world"์—์„œ ์ค‘๊ฐ„์˜ ๊ณต๋ฐฑ ๋•Œ๋ฌธ์— ํ•˜๋‚˜์˜ ํ† ํฐ์œผ๋กœ ์ธ์ง€ x

 

ํฐ ๋”ฐ์˜ดํ‘œ ๋‚ด๋ถ€์— ์ž‘์€ ๋”ฐ์˜ดํ‘œ๋กœ ๊ฐ์‹ธ ์ฃผ๊ฑฐ๋‚˜, + ๋ฅผ ์ด์šฉํ•ด ๋ฌธ์ž์—ด์„ ํ•ฉ์น˜๊ฑฐ๋‚˜, ๋ฆฌํ„ฐ๋Ÿด ๋Œ€์ฒด ๋ฌธ๋ฒ• || ์„ ์‚ฌ์šฉํ•ด ๊ฐ์‹ธ์ฃผ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋ทฐ ํ…œํ”Œ๋ฆฟ


7. ์—ฐ์‚ฐ

ํƒ€์ž„๋ฆฌํ”„ ์—ฐ์‚ฐ์€ ์ž๋ฐ”์™€ ํฌ๊ฒŒ ๋‹ค๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. HTML ์•ˆ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— HTML ์—”ํ‹ฐํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ถ€๋ถ„๋งŒ ์ฃผ์˜ํ•ฉ์‹œ๋‹ค.

@GetMapping("/operation")
public String operate(Model model)
{
    model.addAttribute("nullData",null);
    model.addAttribute("data","Spring!");
    return "basic/operation";
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ul>
    <li> ์‚ฐ์ˆ  ์—ฐ์‚ฐ <ul>
        <li>10 + 2 = <span th:text="10 + 2"></span></li>
        <li>10 % 2 == 0 = <span th:text="10 % 2 == 0"></span></li>
    </ul>
    </li>

    <li>๋น„๊ต ์—ฐ์‚ฐ
    <ul>
        <li>1 > 10 = <span th:text="1 &gt; 10"></span></li>
        <li>1 gt 10 = <span th:text="1 gt 10"></span></li>
        <li>1 >= 10 = <span th:text="1 >= 10"></span></li>
        <li>1 ge 10 = <span th:text="1 ge 10"></span></li>
        <li>1 == 10 = <span th:text="1 == 10"></span></li>
        <li>1 != 10 = <span th:text="1 != 10"></span></li>
    </ul>
    </li>

    <li>์กฐ๊ฑด์‹
        <ul>
        <li>(10 % 2 == 0)? '์ง์ˆ˜':'ํ™€์ˆ˜' = <span th:text="(10 % 2 == 0)? '์ง์ˆ˜':'ํ™€์ˆ˜'"></span></li>
        </ul>
    </li>

    <li>Elvis ์—ฐ์‚ฐ์ž
        <ul>
        <li>${data}?: '๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.' = <span th:text="${data}?: '๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.'"></span></li>
        <li>${nullData}?: '๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.' = <span th:text="${nullData}?: '๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.'"></span></li>
        </ul>
    </li>

    <li>No-Operation
        <ul>
            <li>${data}?: _ = <span th:text="${data}?: _">๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.</span></li>
            <li>${nullData}?: _ = <span th:text="${nulldata}?: _">๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. </span></li>
        </ul>
    </li>
</ul>
</body>
</html>

 

  • ๋น„๊ต์—ฐ์‚ฐ์—์„œ HTML ์—”ํ‹ฐํ‹ฐ (<,>, >=, <=, !, ==, != )๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ถ€๋ถ„๋งŒ ์ฃผ์˜ํ•ฉ์‹œ๋‹ค.
  • ์กฐ๊ฑด์‹ : ์ž๋ฐ”์™€ ๋™์ผ
  • Elvis ์—ฐ์‚ฐ์ž : ์กฐ๊ฑด์‹์˜ ํŽธ์˜ ๋ฒ„์ „
    • ์—˜๋น„์Šค ์—ฐ์‚ฐ์ž๋Š” ?:๋กœ ํ‘œํ˜„ํ•˜๋ฉฐ, ?:์˜ ์™ผ์ชฝ ๊ฐ์ฒด๊ฐ€ non-null์ด๋ฉด ๊ทธ ๊ฐ์ฒด์˜ ๊ฐ’์ด ๋ฆฌํ„ด๋˜๊ณ , null์ด๋ผ๋ฉด ?:์˜ ์˜ค๋ฅธ์ชฝ ๊ฐ’์„ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค. )
  • No operation : _์ธ ๊ฒฝ์šฐ์—๋Š” ๋งˆ์น˜ ํƒ€์ž„๋ฆฌํ”„๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๋Š” ๋ฐ ์ด๊ฒƒ์„ ์ž˜ ํ™œ์šฉํ•˜๋ฉด HTML์˜ ๋‚ด์šฉ ๊ทธ๋Œ€๋กœ ๋ Œ๋”๋ง ํ•  ์ˆ˜ ์žˆ๋‹ค.

8. ์†์„ฑ ๊ฐ’ ์„ค์ •

ํƒ€์ž„๋ฆฌํ”„๋Š” ์ฃผ๋กœ HTML ํƒœ๊ทธ์— th:* ์†์„ฑ์„ ์ง€์ •ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

@GetMapping("/attribute")
public String attribute()
{
    return "basic/attribute";
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>์†์„ฑ ์„ค์ •</h1>
<input type="text" name="mock" th:name="userA"/>
<h1>์†์„ฑ ์ถ”๊ฐ€</h1>
- th:attrappend = <input type="text" class="text" th:attrappend="class=' large'" /><br/>
- th:attrprepend = <input type="text" class="text" th:attrprepend="class='large '" /><br/>
- th:classappend = <input type="text" class="text" th:classappend="large" /><br/>
<h1>checked ์ฒ˜๋ฆฌ</h1>
- checked o <input type="checkbox" name="active" th:checked="true" /><br/>
- checked x <input type="checkbox" name="active" th:checked="false" /><br/>
- checked=false <input type="checkbox" name="active" checked="false" /><br/>
</body>
</html>

์†์„ฑ ์„ค์ •

th:* ๋กœ ์†์„ฑ์„ ์ง€์ •ํ•˜๋ฉด ํƒ€์ž„๋ฆฌํ”„๋Š” ๊ธฐ์กด ์†์„ฑ์„ th:* ๋กœ ์ง€์ •ํ•œ ์†์„ฑ์œผ๋กœ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๊ธฐ์กด ์†์„ฑ์ด ์—†์œผ๋ฉด ์ƒˆ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

ex) <span name="KIM" th:name = "userA"> ์—์„œ ํƒ€์ž„๋ฆฌํ”„๋กœ ๋™์ž‘ํ•˜๋ฉด th:name์ด ๋ Œ๋”๋ง ๋ฉ๋‹ˆ๋‹ค.

 

์†์„ฑ ์ถ”๊ฐ€

  • th:attrappend : ์†์„ฑ ๊ฐ’์˜ ๋’ค์— ๊ฐ’์„ ์ถ”๊ฐ€ (์•ž์— ๋นˆ์นธ)
  • th:attrprepend : ์†์„ฑ ๊ฐ’์˜ ์•ž์— ๊ฐ’์„ ์ถ”๊ฐ€ (๋’ค์— ๋นˆ์นธ)
  • th:classappend : class ์†์„ฑ์— ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ถ”๊ฐ€ (๋นˆ์นธ์„ ์‹ ๊ฒฝ์“ฐ์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค)

Checked ์ฒ˜๋ฆฌ

์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” input ํƒœ๊ทธ์˜ checkbox ์†์„ฑ์—๋Š” chekced ์†์„ฑ ์ด๋ฆ„๋งŒ ์žˆ์œผ๋ฉด ๋ชจ์กฐ๋ฆฌ ์ฒดํฌ๋˜๋Š” ์‚ฌ์–‘์  ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

ํƒ€์ž„๋ฆฌํ”„์—์„œ๋Š” th:checked๋ผ๋Š” ์†์„ฑ์„ ์ œ๊ณตํ•˜๋Š”๋ฐ ์—ฌ๊ธฐ์—” true, false๊ฐ’์„ ์ง€์ •ํ•ด์„œ default ์ฒดํฌ ๊ฐ’์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


9. ๋ฐ˜๋ณต - each

ํƒ€์ž„๋ฆฌํ”„์—์„œ๋Š” th:each๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฐ˜๋ณต์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ถ”๊ฐ€๋กœ ๋ฐ˜๋ณต์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์—ฌ๋Ÿฌ ์ƒํƒœ ๊ฐ’์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

@GetMapping("/each")
public String each(Model model)
{
    addUsers(model);
    return "basic/each";
}

private void addUsers(Model model)
{
    List<User> list = new ArrayList<>();
    list.add(new User("userA",10));
    list.add(new User("userB",20));
    list.add(new User("userC",30));

    model.addAttribute("users",list);
}

 

๋ทฐ ํ…œํ”Œ๋ฆฟ

<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>๊ธฐ๋ณธ ํ…Œ์ด๋ธ”</h1>
<table border="1">
    <tr>
        <th>username</th>
        <th>age</th>
    </tr>
    <tr th:each="user : ${users}">
        <td th:text="${user.username}">username</td>
        <td th:text="${user.age}">0</td>
    </tr>
</table>
<h1>๋ฐ˜๋ณต ์ƒํƒœ ์œ ์ง€</h1>
<table border="1">
    <tr>
        <th>count</th>
        <th>username</th>
        <th>age</th>
        <th>etc</th>
    </tr>
    <tr th:each="user : ${users}">
        <td th:text="${userStat.count}">username</td>
        <td th:text="${user.username}">username</td>
        <td th:text="${user.age}">0</td>
        <td>
            index = <span th:text="${userStat.index}"></span>
            count = <span th:text="${userStat.count}"></span>
            size = <span th:text="${userStat.size}"></span>
            even? = <span th:text="${userStat.even}"></span>
            odd? = <span th:text="${userStat.odd}"></span>
            first? = <span th:text="${userStat.first}"></span>
            last? = <span th:text="${userStat.last}"></span>
            current = <span th:text="${userStat.current}"></span>
        </td>
    </tr>
</table>
</body>
</html>

 

th:each๊ฐ€ ํฌํ•จ๋œ ํƒœ๊ทธ๋ฅผ ํฌํ•จํ•ด์„œ iterator ํ•ฉ๋‹ˆ๋‹ค.

 

๋ทฐ ํ…œํ”Œ๋ฆฟ ์†Œ์Šค

 

  • <tr th:each = "user, userStat : ${users}">
  • ๋‘๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ userStat ๋Š” ์ƒ๋žต ๊ฐ€๋Šฅ, ์ƒ๋žตํ•˜๋ฉด ์ง€์ •ํ•œ ๋ณ€์ˆ˜๋ช…(user) + Stat์ด ๋ฉ๋‹ˆ๋‹ค.
  • ๋‘๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํ†ตํ•ด ๋ฐ˜๋ณต ์ƒํƒœ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๊ธฐ๋Šฅ : index, count, size, even/odd, first/last, current

 

๋ทฐ ํ…œํ”Œ๋ฆฟ


10. ์กฐ๊ฑด๋ถ€ ํ‰๊ฐ€

ํƒ€์ž„๋ฆฌํ”„์˜ ์กฐ๊ฑด์‹

if, unless 

   private void addUsers(Model model)
    {
        List<User> list = new ArrayList<>();
        list.add(new User("userA",10));
        list.add(new User("userB",20));
        list.add(new User("userC",30));

        model.addAttribute("users",list);
    }

    @GetMapping("condition")
    public String condition(Model model)
    {
        addUsers(model);
        return "basic/condition";
    }

 

๋ทฐ ํ…œํ”Œ๋ฆฟ

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>if, unless</h1>
<table border="1">
    <tr>
        <th>count</th>
        <th>username</th>
        <th>age</th>
    </tr>
    <tr th:each="user, userStat : ${users}">
        <td th:text="${userStat.count}">1</td>
        <td th:text="${user.username}">username</td>
        <td>
            <span th:text="${user.age}">0</span>
            <span th:text="'๋ฏธ์„ฑ๋…„์ž'" th:if="${user.age lt 20}"></span>
            <span th:text="'๋ฏธ์„ฑ๋…„์ž'" th:unless="${user.age ge 20}"></span>
        </td> </tr>
</table>

<h1>switch</h1>
<table border="1">
    <tr>
        <th>count</th>
        <th>username</th>
        <th>age</th>
    </tr>
    <tr th:each="user, userStat : ${users}">
        <td th:text="${userStat.count}">1</td>
        <td th:text="${user.username}">username</td>
        <td th:switch="${user.age}">
            <span th:case="10">10์‚ด</span>
            <span th:case="20">20์‚ด</span>
            <span th:case="*">๊ธฐํƒ€</span>
        </td> </tr>
</table>
</body>
</html>

 

if, unless (th:if, th:unless

  • <span th:text="'๋ฏธ์„ฑ๋…„์ž'" th:if="${user.age lt 20}"></span> ์—์„œ if์กฐ๊ฑด์ด ๋งŒ์กฑํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ํƒœ๊ทธ ์ž์ฒด๋ฅผ ๋ Œ๋”๋ง ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • <span th:text="'๋ฏธ์„ฑ๋…„์ž'" th:if="${user.age lt 20}"></span>  ์—์„œ unless(if not) ์กฐ๊ฑด์ด ๋งŒ์กฑํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ํƒœ๊ทธ ์ž์ฒด๋ฅผ ๋ Œ๋”๋ง ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

 

switch (th:switch=${๋ณ€์ˆ˜๋ช…}

  • ์ž๋ฐ” switch-case๋ฌธ๊ณผ ๋™์ผ
  • *์€ ๋งŒ์กฑํ•˜๋Š” ์กฐ๊ฑด์ด ์—†์„ ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋””ํดํŠธ 

๋ทฐ ํ…œํ”Œ๋ฆฟ

 


11. ์ฃผ์„

@GetMapping("/comments")
public String comments(Model model)
{
    model.addAttribute("data","Spring!");
    return "basic/comments";
}

 

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h1>์˜ˆ์‹œ</h1>
<span th:text="${data}">html data</span>
<h1>1. ํ‘œ์ค€ HTML ์ฃผ์„</h1>
<!--<span th:text="${data}">html data</span> -->

<h1>2. ํƒ€์ž„๋ฆฌํ”„ ํŒŒ์„œ ์ฃผ์„</h1>
<!--/* [[${data}]] */-->

<!--/*-->
<span th:text="${data}">html data</span>
<!--*/-->

<h1>3. ํƒ€์ž„๋ฆฌํ”„ ํ”„๋กœํ† ํƒ€์ž… ์ฃผ์„</h1>
<!--/*/
<span th:text="${data}">html data</span>
/*/-->

</body>
</html>

 

  • ํ‘œ์ค€ HTML ์ฃผ์„ <!-- ~~~~ -->
  • ์ผ๋ฐ˜์ ์ธ HTML ์ฃผ์„์œผ๋กœ CSR์—์„œ๋„ ๋ Œ๋”๋งํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ํƒ€์ž„๋ฆฌํ”„ ํŒŒ์„œ ์ฃผ์„  <!--/*  */-->
  • ์ผ๋ฐ˜์ ์ธ ํƒ€์ž„๋ฆฌํ”„ ์ฒ˜๋ฆฌ ์ฃผ์„ (๋ Œ๋”๋ง ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค)
  • ํƒ€์ž„๋ฆฌํ”„ ํ”„๋กœํ† ํƒ€์ž… ์ฃผ์„ <!--/*/  ~~~~~ /*/ --> 
  • HTML ํŒŒ์ผ์„ ์›น๋ธŒ๋ผ์šฐ์ €์—์„œ ๊ทธ๋Œ€๋กœ ์—ด์–ด๋ณด๋ฉด HTML ์ฃผ์„์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ถ€๋ถ„์ด ์›น ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ Œ๋”๋ง ํ•˜์ง€ ์•Š์ง€๋งŒ, ํƒ€์ž„๋ฆฌํ”„ ๋ Œ๋”๋ง์„ ํ•œ ๊ฒฝ์šฐ์—๋Š” ๋ณด์ด๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

๋ทฐ ํ…œํ”Œ๋ฆฟ

 


12. ๋ธ”๋ก

<th:block> ์€ HTML ํƒœ๊ทธ๊ฐ€ ์•„๋‹Œ ์œ ์ผํ•œ ํƒ€์ž„๋ฆฌํ”„์˜ ์ž์ฒด ํƒœ๊ทธ์ž…๋‹ˆ๋‹ค.

@GetMapping("/block")
public String block(Model model)
{
    addUsers(model);
    return "basic/block";
}

 

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<th:block th:each="user : ${users}">
  <div>
    ์‚ฌ์šฉ์ž ์ด๋ฆ„1 <span th:text="${user.username}"></span>
    ์‚ฌ์šฉ์ž ๋‚˜์ด1 <span th:text="${user.age}"></span>
  </div>
  <div>
    ์š”์•ฝ <span th:text="${user.username} + ' / ' + ${user.age}"></span>
  </div>
</th:block>
</body>
</html>

 

์œ„์™€ ๊ฐ™์ด (์‚ฌ์šฉ์ž์ด๋ฆ„, ๋‚˜์ด)๊ฐ€ ํ•˜๋‚˜์˜ div ํƒœ๊ทธ์— (์š”์•ฝ)์ด ํ•˜๋‚˜์˜ divํƒœ๊ทธ์— ๋‹ด๊ฒจ์žˆ์Šต๋‹ˆ๋‹ค.

th:block์€ ๋ง ๊ทธ๋Œ€๋กœ ํ•˜๋‚˜์˜ ๋ธ”๋ก์ฒ˜๋ฆฌ๋ฅผ ํ•˜์—ฌ ๋ฐ˜๋ณต๋ฌธ์„ ๋Œ๋ฆฌ๊ฒŒ ํ•ด์คŒ์œผ๋กœ์จ (์‚ฌ์šฉ์ž ์ด๋ฆ„, ๋‚˜์ด, ์š”์•ฝ) ์ด ํ•œ ๋ธ”๋ก์•ˆ์— ๋‚˜์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋ทฐํ…œํ”Œ๋ฆฟ

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<span th:each="user : ${users}">
  <div>
    ์‚ฌ์šฉ์ž ์ด๋ฆ„1 <span th:text="${user.username}"></span>
    ์‚ฌ์šฉ์ž ๋‚˜์ด1 <span th:text="${user.age}"></span>
  </div>
</span>

<span th:each="user : ${users}">
  <div>
    ์š”์•ฝ <span th:text="${user.username} + ' / ' + ${user.age}"></span>
  </div>
</span>
</body>
</html>

 

th:block์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  th:each๋ฌธ ๋‘๊ฐœ๋กœ ๋‚˜๋ˆ„์—ˆ์„ ๋•Œ

์ด๋ ‡๊ฒŒ ๋‚˜๋ˆ ์ง„ ๋ฐ˜๋ณต๋ฌธ์„ th:block์„ ์‚ฌ์šฉํ•˜๋ฉด ์›ํ์— ๋Œ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


13. ์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ ์ธ๋ผ์ธ

ํƒ€์ž„๋ฆฌํ”„๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ํƒ€์ž„๋ฆฌํ”„๋ฅผ ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ธ๋ผ์ธ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

@GetMapping("/javascript")
public String javascript(Model model) {
    model.addAttribute("user", new User("userA", 10));
    addUsers(model);
    return "basic/javascript";
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!-- ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ธ๋ผ์ธ ์‚ฌ์šฉ ์ „ -->
<script>
    var username = [[${user.username}]];
    var age = [[${user.age}]];

    //์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋‚ด์ถ”๋Ÿด ํ…œํ”Œ๋ฆฟ
    var username2 = /*[[${user.username}]]*/ "test username";

    //๊ฐ์ฒด
    var user = [[${user}]];
</script>


<!-- ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ธ๋ผ์ธ ์‚ฌ์šฉ ํ›„ -->
<script th:inline="javascript">
    var username = [[${user.username}]];
    var age = [[${user.age}]];

    //์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋‚ด์ถ”๋Ÿด ํ…œํ”Œ๋ฆฟ
    var username2 = /*[[${user.username}]]*/ "test username";

    //๊ฐ์ฒด
    var user = [[${user}]];
</script>

<!-- ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ธ๋ผ์ธ ์‚ฌ์šฉ ํ›„ -->
<script th:inline="javascript">
    [# th:each="user : ${users}"]
    var user[[${userStat.count}]] = [[${user}]];
    [/]
</script>
</body>
</html>

 

๋ทฐํ…œํ”Œ๋ฆฟ ์†Œ์Šค์ฝ”๋“œ

ํ…์ŠคํŠธ ๋ Œ๋”๋ง 

  • var username = [[${user.username}]];
  • ์ธ๋ผ์ธ ์‚ฌ์šฉ ์ „ : var username = userA;
  • ์ธ๋ผ์ธ ์‚ฌ์šฉ ํ›„ : var username = "userA";

๊ฒฐ๊ณผ์ ์œผ๋กœ ์ธ๋ผ์ธ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด userA๊ฐ€ ๋ณ€์ˆ˜๋ช…์œผ๋กœ ์‚ฌ์šฉ๋˜์–ด์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒ.

age์˜ ๊ฒฝ์šฐ๋Š” ์ˆซ์ž๊ธฐ ๋•Œ๋ฌธ์— ์ •์ƒ ๋ Œ๋”๋ง์ด ๋ฉ๋‹ˆ๋‹ค.

 

์ธ๋ผ์ธ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ Œ๋”๋ง ๊ฒฐ๊ณผ์— ๋ฌธ์ž ํƒ€์ž…์ธ ๊ฒฝ์šฐ "๋ฅผ ํฌํ•จํ•ด์ค๋‹ˆ๋‹ค. ์ถ”๊ฐ€๋กœ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ž๊ฐ€ ํฌํ•จ๋˜์–ด์žˆ์œผ๋ฉด ์ด์Šค์ผ€์ดํ”„ ์ฒ˜๋ฆฌ๋„ ํ•ด์ค๋‹ˆ๋‹ค. ex) " -> \"

 

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋‚ด์ธ„๋Ÿด ํ…œํ”Œ๋ฆฟ

ํƒ€์ž„๋ฆฌํ”„๋Š” HTML ํŒŒ์ผ์„ ์ง์ ‘ ์—ด์–ด๋„ ๋™์ž‘ํ•˜๋Š” ๋‚ด์ธ„๋Ÿด ํ…œํ”Œ๋ฆฟ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ธ๋ผ์ธ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ฃผ์„์„ ํ™œ์šฉํ•ด ์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ธ๋ผ์ธ ์‚ฌ์šฉ ์ „ : var username2 = /*userA*/ "test username";
  • ์ธ๋ผ์ธ ์‚ฌ์šฉ ํ›„ : var username2 = "userA";

๊ฐ์ฒด

๊ฐ์ฒด๋ฅผ JSON์œผ๋กœ ์ž๋™์œผ๋กœ ๋ณ€ํ™˜ํ•ด์ค๋‹ˆ๋‹ค.

  • var user = [[${user}]];
  • ์ธ๋ผ์ธ ์‚ฌ์šฉ ์ „ : var user = BasicController.User(username=userA, age=10);
  • ์ธ๋ผ์ธ ์‚ฌ์šฉ ํ›„ : var user = {"username":"userA", "age":10};

 

์ธ๋ผ์ธ์—์„œ๋„ each๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

<!-- ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ธ๋ผ์ธ ์‚ฌ์šฉ ํ›„ -->
<script th:inline="javascript">
    [# th:each="user : ${users}"]
    var user[[${userStat.count}]] = [[${user}]];
    [/]
</script>
</body>

๊ฒฐ๊ณผ

  <script>
  var user1 = {"username":"userA","age":10};
  var user2 = {"username":"userB","age":20};
  var user3 = {"username":"userC","age":30};
  </script>

[# th:each="user : ${users}"] ~~ [/]

 

 

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

Study Repository

rlaehddnd0422

ํ™œ๋™ํ•˜๊ธฐ