SPRING
2018.09.23 / 16:10

Thymeleaf¿¡¼­ ÅÛÇø´ Çü½ÄÀ¸·Î »ç¿ëÇϱâ(With thymeleaf-layout-dialect)

hangawee
Ãßõ ¼ö 178

JSP¸¸ ¾²´Ù°¡¡¦

»ç½Ç Àú´Â Spring boot¸¦ ¾´Áö´Â ¾ó¸¶ µÇÁö ¾Ê¾Ò½À´Ï´Ù.
±× Àü¿¡´Â Spring + Jsp + mybatis Á¶ÇÕÀ» ¸¹ÀÌ »ç¿ëÇÏ¿´Áö¿ä.
Spring Boot¸¦ Á¢ÇÏ°Ô µÈ °ÍÀº 4¿ù´Þ ÂêÀ½ ÅäÀÌ ÇÁ·ÎÁ§Æ®¸¦ Çϳª ÁøÇàÇϸ鼭 ¾²°Ô µÇ¾ú½À´Ï´Ù.
SpringÀ» ¾²´Ù°¡ Spring Boot¸¦ »ç¿ëÇÏ¿´À» ¶§´Â ½Å¼¼°è ¿´½À´Ï´Ù.
Spring Boot¿¡¼­´Â View´ÜÀ» JSPº¸´Ù´Â Thymeleaf¶ó´Â °ÍÀ» »ç¿ëÇÏ±æ ±ÇÀåÇÏ°í ÀÖ½À´Ï´Ù.

Thymeleaf´Â ¼ø¼ö HTML¿¡ HTML5¹®¹ýÀ» »ç¿ëÇÏ¿© Server side ·ÎÁ÷À» ¼öÇàÇÒ ¼ö Àִ HTML ÅÂ±× ¹× ¼Ó¼º ±â¹ÝÀÇ Template EngineÀÔ´Ï´Ù.
ÀÏ´Ü Spring Boot ¿¡¼­´Â JSP¸¦ ¾²·Á¸é ¾à°£ º¹ÀâÇØÁý´Ï´Ù.
¸¸¾à Spring Boot ¿¡¼­ JSP¸¦ ¾²±æ ¿øÇѴٸ頰ø½Ä¹®¼­ ¿¹Á¦¸¦ Âü°íÇϼ¼¿ä.
(·¯´×Ä¿ºêµµ ³ôÀº Æíµµ ¾Æ´Ï¶ó Çѹø ½áº¸½Ã´Â °ÍÀ» Ãßõ µå¸³´Ï´Ù :) )

¼­·ÐÀº ¿©±â±îÁö·Î ÇÏ°í¡¦
Á¦°¡ Thymeleaf¸¦ ¾²¸é¼­ °øÅë ·¹À̾ƿô¿¡ ´ëÇÑ Ã³¸®¸¦ ÇÑ ºÎºÐ¿¡ ´ëÇØ Æ÷½ºÆÃÀ» Çغ¸°íÀÚ ÇÕ´Ï´Ù.
½ÃÀÛÇϱ⠾ռ­ °³¹ßȯ°æÀº ´ÙÀ½°ú °°½À´Ï´Ù.

  • Spring Boot = ¡®1.5.8.RELEASE¡¯
  • dependencies = compile(¡®org.springframework.boot:spring-boot-starter-thymeleaf¡¯)


spring-boot-starter-thymeleaf¿¡´Â?

¸ÕÀú ¿¹Á¦¸¦ »ìÆ캸±â ÀÌÀü¿¡¡¦
°³¹ßȯ°æ¿¡¼­ ÀÇÁ¸¼º¿¡ spring-boot-starter¿¡ ´Ù¾çÇÑ °ÍÀÌ ÀÖÁö¸¸ ±× Áß thymeleaf¸¦ »ç¿ëÇÏ¿´½À´Ï´Ù.
ÀÌ ÀÇÁ¸¼ºÀº ´ÙÀ½°ú °°ÀÌ ±¸¼ºµÇ¾î ÀÖ½À´Ï´Ù.

ÀÌ Áß ¸Ç ¸¶Áö¸·¿¡ Ãß°¡µÈ Thymeleaf Layout Dialect´Â ŸÀÓ¸®ÇÁ¿¡¼­ ÄÚµå Àç»ç¿ëÀ» °³¼±Çϱâ À§ÇØ Àç»ç¿ëÀÌ °¡´ÉÇÑ ·¹À̾ƿô°ú ÅÛÇø´À» ÀÛ¼ºÇÒ ¼ö ÀÖµµ·Ï µµ¿ÍÁÖ´Â ¶óÀ̺귯¸®ÀÔ´Ï´Ù.
ÀÌ°Í¿¡ ´ëÇÑ Æ÷½ºÆÃÀº Thymeleaf¿¡¼­ thymeleaf-layout-dialect ¼Ò°³ Æ÷½ºÆø¦ Âü°íÇØÁÖ¼¼¿ä.


¿¹Á¦¿¡ ¾Õ¼­

¿¹Á¦´Â Á¦°¡ ¿ÀǼҽº·Î ¸¸µé°í Àִ CompanyBoard¿¡¼­ ¾²ÀÎ ºÎºÐÀÔ´Ï´Ù.
thymeleaf-layout-dialect¸¦ »ç¿ëÇÏ¿© °øÅëÀûÀ¸·Î »ç¿ëÇÏ´Â ·¹À̾ƿôÀ» ¸¸µé°í, ÄÁÅÙÃ÷ ÆäÀÌÁö¿¡ °øÅë ·¹À̾ƿôÀ» Àû¿ëÇÏ´Â ¼ø¼­·Î ÁøÇàÇÏ°Ú½À´Ï´Ù.


1. °øÅëÀûÀ¸·Î »ç¿ëÇÒ Main Layout ÀÛ¼º

HTMLÀ̶ó¸é ´ÙÀ½°ú °°Àº ±âº» ¾ç½ÄÀ» µû¸¦ °ÍÀÔ´Ï´Ù.

1
2
3
4
5
6
¿¹Á¦ÆÄÀÏ À̸§ : layout/main_layout.html
<!DOCTYPE html>
<html lang="ko" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head th:replace="fragments/main/main_header :: mainHead"> </head>
<body th:replace="fragments/main/main_body :: mainBody"> </body>
</html>

html ÅÂ±× ¾È¿¡ head¿Í body°¡ ±¸¼ºµÇ´Âµ¥ ÀúÀÇ °æ¿ì À§ ¿¹Á¦Ã³·³ Å« ƲÀÇ °øÅë ·¹À̾ƿôÀ» Àâ°í, head¿Í body ¿µ¿ª¿¡¼­ th:replace ¼Ó¼ºÀ» ÅëÇØ °¢ ºÎºÐ¿¡ ´ëÇÑ °øÅë ·¹À̾ƿôÀ» ÀçÁ¤ÀÇ ÇÏ¿´½À´Ï´Ù.

th:replace ¼Ó¼ºÀº °£´ÜÇÏ°Ô ¼³¸íÇϸé ÇØ´ç ¼Ó¼ºÀÌ ¼±¾ðµÈ html ű׸¦ replace¿¡ Á¤ÀÇµÈ ´Ù¸¥ html ÆÄÀϷΠġȯÇÏ´Â °ÍÀ¸·Î jspÀÇ include¿Í ºñ½ÁÇÑ µ¿ÀÛÀ» ÇàÇÕ´Ï´Ù.

th:replace ¼Ó¼ºÀÇ °æ·Î´Â Spring-bootÀÇ ±âº» °æ·ÎÀΠtemplates ÇÏÀ§¿¡ Á¤ÀÇÇÑ °æ·Î¸¦ ÀÛ¼º ÈÄ :: µÚ¿¡´Â ¾Æ·¡¿¡¼­ ¼Ò°³ÇÒ fragment¼Ó¼ºÀÇ À̸§À» Àû¾îÁÝ´Ï´Ù.


2. HeadÀÇ °øÅë ºÎºÐ ÀÛ¼º

headÀÇ °øÅë ºÎºÐÀº ¾Æ·¡ÀÇ ¿¹Á¦¿Í °°½À´Ï´Ù.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
¿¹Á¦ÆÄÀÏ À̸§ : fragments/main/main_header.html
<!DOCTYPE html>
<html lang="ko" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head th:fragment="mainHead">
<th:block th:include="fragments/common/c_head"></th:block>

<link rel="stylesheet" th:href="@{/lib/AdminLTE-2.4.2/css/AdminLTE.min.css}" />
<link rel="stylesheet" th:href="@{/lib/AdminLTE-2.4.2/css/skins/_all-skins.css}" />

<link rel="stylesheet" th:href="@{/css/common/common_main.css}" />

//Custom or page css
<th:block layout:fragment="custom_css"></th:block>

</head>
</html>

head ű׿¡¼­ º¸¸é fragment ¼Ó¼º¿¡ À̸§À» Á¤ÀÇÇÏ¿´°í, th:include¼Ó¼º°ú css ¼±¾ð, ±×¸®°í ÄÁÅÙÃ÷ ÆäÀÌÁö¿¡¼­ »ç¿ëÇÒ ¿µ¿ªÀΠlayout:fragment=¡±custom_css¡±¸¦ Á¤ÀÇÇÏ¿´´Ù.

th:include=¡±fragments/common/c_head¡±¼Ó¼ºÀÇ ÆÄÀÏÀº ´ÙÀ½°ú °°ÀÌ ±¸¼ºµÇ¾î ÀÖ´Ù.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
¿¹Á¦ÆÄÀÏ À̸§ : fragments/common/c_head.html
//Meta Data
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>

//±âº»ÀûÀÎ html head Ãß°¡ºÎ
<th:block layout:fragment="html_head"></th:block>

//Css lib
<link rel="stylesheet" th:href="@{/lib/AdminLTE-2.4.2/bower_components/bootstrap/dist/css/bootstrap.min.css}" />
<link rel="stylesheet" th:href="@{/lib/sweetalert2/sweetalert2.min.css}" />
<link rel="stylesheet" th:href="@{/lib/font-awesome-4.7.0/css/font-awesome.min.css}" />

//Etc Add on Lib
<th:block layout:fragment="add_lib_css"></th:block>

//Css custom
<link rel="stylesheet" th:href="@{/css/common/loading.css}" />
<link rel="stylesheet" th:href="@{/css/common/common_main.css}" />

layout:fragment=¡±html_head¡±¼Ó¼ºÀº ÄÁÅÙÃ÷ ÆäÀÌÁö¿¡¼­ titleÀ» Á¤ÀÇÇÏ´Â ºÎºÐÀ¸·Î ½ÇÁ¦ ÄÁÅÙÃ÷ ÆäÀÌÁö¿¡¼­ ¾Ë¸Â°Ô »ç¿ëÇϸç, 4¹ø ÄÁÅÙÃ÷ ÆäÀÌÁö ³»¿ëÀ» Âü°íÇϼ¼¿ä.
Áß°£ÀÇ add_lib_css¿µ¿ªÀº ÄÁÅÙÃ÷ ÆäÀÌÁö¿¡¼­ µû·Î Ãß°¡ÀûÀ¸·Î »ç¿ëÇÒ css µîÀ» Ãß°¡ÇÏ´Â ¿µ¿ªÀÔ´Ï´Ù.

°£·«È÷ Á¤¸®¸¦ ÇÏÀÚ¸é layout:fragment ¼Ó¼ºÀº °øÅë ·¹À̾ƿô¿¡¼­ ¼±¾ðÇÏ¿© ½ÇÁ¦ ÄÁÅÙÃ÷ ÆäÀÌÁö¿¡¼­ ¼±¾ðµÈ ³»¿ëÀ» ä¿ì°Ô ÇØÁÝ´Ï´Ù.


3. BodyÀÇ °øÅë ºÎºÐ ÀÛ¼º

1¹ø¿¡¼­ ÀÛ¼ºÇÑ Äڵ忡¼­ body ¿µ¿ªÀ» º¸°Ú½À´Ï´Ù.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
¿¹Á¦ÆÄÀÏ À̸§ : fragments/main/main_body.html
<!DOCTYPE html>
<html lang="ko" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">

<body th:fragment="mainBody">
<div class="wrapper">
<th:block layout:fragment="content_body"></th:block>
<th:block th:include="fragments/main/main_footer"></th:block>
</div>

<th:block th:include="fragments/common/c_body_script"></th:block>

<script th:src="@{/lib/AdminLTE-2.4.2/js/adminlte.min.js}"></script>
<script th:src="@{/js/common/common_main.js}"></script>

<th:block layout:fragment="custom_js"></th:block>

</body>
</html>

body ¿µ¿ªÀº ½ÈÁ¦ ÄÁÅÙÃ÷ ÆäÀÌÁö¸¦ ä¿ï ¿µ¿ªÀΠlayout:fragment=¡±content_body¡±ÀÌ ¼±¾ðµÇ¾î ÀÖ°í, °øÅëÀûÀ¸·Î »ç¿ëÇÒ footer¸¦ include ÇÏ°Ô µË´Ï´Ù.

¾Æ·¡ÀÇ ¿µ¿ªÀº JS¸¦ ¼±¾ðÇÏ¿© »ç¿ëÇÏ´Â ¿µ¿ªÀÔ´Ï´Ù.


4. ÄÁÅÙÃ÷ ÆäÀÌÁö ÀÛ¼º

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
<!DOCTYPE html>
<html lang="ko" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorator="layout/main_layout">

<th:block layout:fragment="html_head">
<title>TachyonTech Info</title>
</th:block>

<th:block layout:fragment="add_lib_css">
<link rel="stylesheet" th:href="@{/lib/fullcalendar-3.6.2/fullcalendar.min.css}" />
<link rel="stylesheet" th:href="@{/lib/fullcalendar-3.6.2/fullcalendar.print.min.css}" media="print" />
</th:block>

<th:block layout:fragment="custom_css">
<link rel="stylesheet" th:href="@{/css/dashboard/main.css}" />
</th:block>


<th:block layout:fragment="content_body">
<div th:replace="fragments/common/loading"></div>
<header th:include="fragments/main/main_sidemenu"></header>

<div class="content-wrapper">
//..... ½ÇÁ¦ ÄÁÅÙÃ÷ ³»¿ë ÀÛ¼º
</div>
</th:block>


<th:block layout:fragment="custom_js">
<script th:src="@{/lib/fullcalendar-3.6.2/fullcalendar.min.js}"></script>

<script th:src="@{/js/dashboard/main.js}"></script>
</th:block>

</html>

ÄÁÅÙÃ÷ ÆäÀÌÁö´Â À§ÀÇ ¿¹Á¦¸¦ Âü°íÇÏ½Ã¸é µË´Ï´Ù.
óÀ½ º¸¸é ¾à°£Àº º¹ÀâÇÏÁö¸¸, À§ÀÇ ¿¹Á¦¸¦ Çϳª¾¿ È帧¿¡ ¸ÂÃç¼­ º¸°Ô µÇ¸é ±×¸® ¾î·ÆÁöµµ ¾Ê½À´Ï´Ù.
±×¸®°í ÀÌÇØ ÈÄ »ç¿ëÇÏ°Ô µÇ¸é ·¹À̾ƿô¿¡ ´ëÇÑ °øÅëÀûÀÎ ºÎºÐÀ» ½±°Ô ±¸ÇöÇÒ ¼ö ÀÖÀ¸¸ç, ÄÚµå º¹Àâµµµµ ³·¾ÆÁö°Ô µË´Ï´Ù.


°á·Ð

À§ÀÇ ¿¹Á¦¸¦ ¾à°£ Á¤¸®ÇÏ¸é ´ÙÀ½°ú °°½À´Ï´Ù.

  • »óÀ§ °øÅë ·¹À̾ƿô -> layout/main_layout.html
  • head °øÅë ·¹À̾ƿô -> fragments/main/main_header.html -> fragments/common/c_head.html
  • body °øÅë ·¹À̾ƿô -> fragments/main/main_body.html
  • À§ÀÇ °øÅë ·¹À̾ƿôµéÀ» ¹­¾î¼­ ÄÁÅÙÃ÷ ÆäÀÌÁö ÀÛ¼º

Æ÷½ºÆÃÀÇ ³»¿ëÀÌ ¾à°£ ±æ°Ô µÇ¾î Á¦°¡ ÀÚ¼¼ÇÏ°Ô ÀûÁö ¸øÇÑ ºÎºÐµµ ÀÖÀ» ¼ö ÀÖ½À´Ï´Ù.
ÀÌÇØ°¡ ¾ÈµÇ½Ã°Å³ª À߸øµÈ ºÎºÐÀÌ ÀÖ´Ù¸é ¸ÞÀÏ µîÀ¸·Î ¾Ë·ÁÁÖ½Ã¸é ´äº¯ ¶Ç´Â ¼öÁ¤ ó¸®Çϵµ·Ï ÇÏ°Ú½À´Ï´Ù.

°¨»çÇÕ´Ï´Ù.