3 분 소요

 인프런 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술편을 학습하고 정리한 내용 입니다.

주석

BasicController

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

/resources/templates/basic/comments.html

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
26
27
28
29
30
<!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 주석은 타임리프가 렌더링 하지 않고, 그대로 남겨둔다.

타임리프 파서 주석

<!--/* + 내용 + */-->

타임리프 파서 주석은 타임리프의 진짜 주석이다. 렌더링에서 주석 부분을 제거한다.

타임리프 프로토타입 주석

<!--/*/ + 내용 + /*/-->

타임리프 프로토타입은 약간 특이한데, HTML 주석에 약간의 구문을 더했다. HTML 파일을 웹 브라우저에서 그대로 열어보면 HTML 주석이기 때문에 이 부분이 웹 브라우저가 렌더링하지 않는다.

타임리프 렌더링을 거치면 이 부분이 정상 렌더링 된다.

쉽게 이야기해서 HTML 파일을 그대로 열어보면 주석 처리가 되지만, 타임리프를 렌더링 한 경우에만 보이는 기능이다.

잘 안쓸거 같긴 하다..

블록

<th:block> 은 HTML 태그가 아닌 타임리프의 유일한 자체 태그다.

BasicController

1
2
3
4
5
@GetMapping("/block")  
public String block(Model model) {  
    addUser(model);  
    return "basic/block";  
}

/resources/templates/basic/block.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!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>

타임리프의 특성 상 HTML 태그 안에 속성으로 기능을 정의해서 사용하는데, 위 예처럼 이렇게 사용하기 애매한 경우에 사용하면 된다. (div 2개를 한번에 반복해야 해서)

<th:block>은 렌더링 시 제거된다

자바스크립트 인라인

타임리프는 자바스크립트에서 타임리프를 편리하게 사용할 수 있는 자바스크립트 인라인 기능을 제공한다.

자바스크립트 인라인 기능은 다음과 같이 사용 한다.

<script th:inline="javascript">

BasicController

1
2
3
4
5
6
7
@GetMapping("/javascript")  
public String javascript(Model model) {  
    model.addAttribute("user", new User("userA", 10));  
    addUser(model);  
  
    return "basic/javascript";  
}

/resources/templates/basic/javascript.html

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<!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>  
  
<!-- 자바스크립트 인라인 each --><script th:inline="javascript">  
  
    [# th:each="user, stat : ${users}"]  
    var user[[${stat.count}]] = [[${user}]];  
    [/]  
  
</script>  
  
</body>  
</html>

자 사용 전 항목 var username = [[${user.username}]]; 가 렌더링 된 걸 보자.

"userA" 가 되어야 하는데, 그냥 userA라 나온다.

제대로 하려면 var username = "[[${user.username}]]"; 이런 식으로 해줘야 할 것이다.

다른 부분도 문제가 많다.

텍스트 렌더링

  • var username = [[${user.username}]];
    • 인라인 사용 전 → var username = userA;
    • 인라인 사용 후 → var username = "userA";

인라인 사용 전 렌더링 결과를 보면 userA가 변수 이름 그대로 남아있다. 타임리프 입장에서는 정확하게 렌더링 한 것이지만

아마 개발자가 기대한 것은 "userA"일 것이다.

결과적으로 userA가 변수 명으로 사용되어서 자바스크립트 오류가 발생한다.

인라인 사용 후 렌더링 결괄르 보면 문자 타입인 경우 "를 추가해 준다.

추가로 자바스크립트 에서 문제가 될 수 있는 문자가 포함되어 있으면 이스케이프 처리도 해준다. 예) "\"

자바스크립트 내추럴 템플릿

타임리프는 HTML 파일을 직접 열어도 동작하는 내추럴 템플릿 기능을 제공한다.

자바스크립트 인라인 기능을 사용하면 주석을 활용해서 이 기능을 사용할 수 있다.

  • var username2 = /*[[${user.username}]]*/ "test username";
    • 인라인 사용 전 → var username2 = /*userA*/ "test username";
    • 인라인 사용 후 → var username2 = "userA";

인라인 사용 전 결과를 보면 정말 순수하게 그대로 해석 했다.

따라서 내추럴 템플릿 기능이 동작하지 않고, 심지어 렌더링 내용이 주석 처리 되어 버린다.

인라인 사용 후 결과를 보면 주석 부분이 제거되고, 기대한 "userA"가 정확하게 적용된다.

객체

타임리프의 자바스크립트 인라인 기능을 사용하면 객체를 JSON으로 자동으로 변환해준다.

  • var user = [[${user}]];
    • 인라인 사용 전 → var user = BasicController.User(username=userA, age=10);
    • 인라인 사용 후 → var user = {"username":"userA","age":10};

인라인 사용 전에는 객체를 toString()으로 호출해 버린다.

인라인 사용 후에는 객체를 JSON으로 변환해 준다.

자바스크립트 인라인 each

자바스크립트 인라인은 each를 지원하는데, 다음과 같이 사용한다.

1
2
3
4
5
6
7
<script th:inline="javascript">  
  
    [# th:each="user, stat : ${users}"]  
    var user[[${stat.count}]] = [[${user}]];  
    [/]  
  
</script>

결과

1
2
3
4
5
6
7
<script>
    
    var user1 = {"username":"userA","age":10};
    var user2 = {"username":"userB","age":20};
    var user3 = {"username":"userC","age":30};
    
</script>

댓글남기기