오늘은 Spring Boot에서 자주 사용하는 타임리프 템플릿 엔진에 대해서 알아보겠습니다. 템플릿 엔진이 무엇인지 알고 싶으시다면 여기를 클릭해주세요.
1. Spring MVC 템플릿 엔진 VS Spring Boot 템플릿 엔진
Java Object에서 데이터를 생성하여 Template에 넣어주면 템플릿 엔진에서 Template에 맞게 변환하여 html을 생성하고 클라이언트에게 제공합니다.
Spring Template Engine | Spring Boot Template | |
종류 | JSP, Thymeleaf, Groovy, Freemarker, Jade4j, JMustache, Pebble, Handlebars, Velocity | Mustache, Thymeleaf, Groovy, Freemarker |
추천 | Thymeleaf | Handlebars, Mustache |
비추천 | Velocity는 Spring 버전 4.3부터 사용 중단 | Freemarker, JSP |
자주사용되는 jsp의 경우 임베디드 서블릿 컨테이너를 사용하는 Spring Boot에서는 제한 사항이 있습니다. 공식문서를 참고해주세요.
2. 타임리프(Thymeleaf)란?
이제 제가 자주 사용하는 타임리프 템플릿엔진에 대해서 알아보겠습니다. 타임리프는 HTML, XML, JavaScript, CSS, text를 생성하기 위한 자바 템플릿 엔진입니다. 이 라이브러리는 확장성이 매우 높으며 기본 템플릿기능만으로 백엔드 없이 템플릿을 프로토타입화 할 수 있습니다. 스프링에서 타임리프를 사용하기 위해서는 Maven POM.XML에 다음 의존성을 추가해야합니다.
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
Spring 3 에서는 thymeleaf-spring4 대신 thymeleaf-spring3 라이브러리를 사용해야합니다.
Spring Template Engine은 환경설정의 모든 단계를 수행합니다. 여러분의 자바 환경설정 파일에 하나의 빈으로서 이 클래스를 다음과 같이 구현할 수 있습니다.
@Bean
@Description("Thymeleaf Template Resolver")
public ServletContextTemplateResolver templateResolver() {
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver();
templateResolver.setPrefix("/WEB-INF/views/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
return templateResolver;
}
@Bean
@Description("Thymeleaf Template Engine")
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.setTemplateEngineMessageSource(messageSource());
return templateEngine;
}
templateResolver 의 속성 중 prefix 는 webapp 디렉토리 내의 뷰페이지 위치를 가리키며 suffix 는 뷰페이지들에 포함되는 파일들의 확장자를 의미합니다.
Spring MVC 의 ViewResolver 인터페이스는 컨트롤러가 반환하는 뷰 이름들과 실제 뷰 객체들을 매핑합니다. ThymeleafViewResolver 는 ViewResolver 인터페이스를 구현하며 주어진 뷰 이름을 렌더링 하기 위해 어느 Thymeleaf 뷰들을 사용할지를 결정하는데 사용됩니다.
마지막 통합 단계은 ThymeleafViewResolver 를 빈으로 추가하는 것입니다.
@Bean
@Description("Thymeleaf View Resolver")
public ThymeleafViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
viewResolver.setOrder(1);
return viewResolver;
}
3. 자주 사용하는 문법 및 표현식
TitleDescription
th:text |
텍스트 내용 <span th:text="${user.name}"></span> |
th:utext |
html 내용 <div th:utext="${content}"></div> |
th:value |
element value값, checkbox, input 등 <input type="text" th:value="${title}" /> |
th:with |
변수값 지정 <p th:with="authType = ${user.authType}+' Type'" th:text="${authType}"></p> |
th:switch th:case |
switch-case문 <div th:switch="${user.role}"> <p th:case="'admin'">User is an administrator <p th:case="#{roles.manager}">User is a manager</div> |
th:if | 조건문 <p th:if="${user.authType}=='web'" th:text="${user.authType}"></p> |
th:unless |
else 표현 <p th:unless="${user.authType}=='facebook'" th:text="'not '+ ${user.authType}"></p> |
th:each | 반복문 <p th:each="user : ${users}" th:text="${user.name}"></p> |
* 참고 *
There are quite a lot of attributes like these, each of them targeting a specific HTML5 attribute:
th:abbr | th:accept | th:accept-charset |
th:accesskey | th:action | th:align |
th:alt | th:archive | th:audio |
th:autocomplete | th:axis | th:background |
th:bgcolor | th:border | th:cellpadding |
th:cellspacing | th:challenge | th:charset |
th:cite | th:class | th:classid |
th:codebase | th:codetype | th:cols |
th:colspan | th:compact | th:content |
th:contenteditable | th:contextmenu | th:data |
th:datetime | th:dir | th:draggable |
th:dropzone | th:enctype | th:for |
th:form | th:formaction | th:formenctype |
th:formmethod | th:formtarget | th:fragment |
th:frame | th:frameborder | th:headers |
th:height | th:high | th:href |
th:hreflang | th:hspace | th:http-equiv |
th:icon | th:id | th:inline |
th:keytype | th:kind | th:label |
th:lang | th:list | th:longdesc |
th:low | th:manifest | th:marginheight |
th:marginwidth | th:max | th:maxlength |
th:media | th:method | th:min |
th:name | th:onabort | th:onafterprint |
th:onbeforeprint | th:onbeforeunload | th:onblur |
th:oncanplay | th:oncanplaythrough | th:onchange |
th:onclick | th:oncontextmenu | th:ondblclick |
th:ondrag | th:ondragend | th:ondragenter |
th:ondragleave | th:ondragover | th:ondragstart |
th:ondrop | th:ondurationchange | th:onemptied |
th:onended | th:onerror | th:onfocus |
th:onformchange | th:onforminput | th:onhashchange |
th:oninput | th:oninvalid | th:onkeydown |
th:onkeypress | th:onkeyup | th:onload |
th:onloadeddata | th:onloadedmetadata | th:onloadstart |
th:onmessage | th:onmousedown | th:onmousemove |
th:onmouseout | th:onmouseover | th:onmouseup |
th:onmousewheel | th:onoffline | th:ononline |
th:onpause | th:onplay | th:onplaying |
th:onpopstate | th:onprogress | th:onratechange |
th:onreadystatechange | th:onredo | th:onreset |
th:onresize | th:onscroll | th:onseeked |
th:onseeking | th:onselect | th:onshow |
th:onstalled | th:onstorage | th:onsubmit |
th:onsuspend | th:ontimeupdate | th:onundo |
th:onunload | th:onvolumechange | th:onwaiting |
th:optimum | th:pattern | th:placeholder |
th:poster | th:preload | th:radiogroup |
th:rel | th:rev | th:rows |
th:rowspan | th:rules | th:sandbox |
th:scheme | th:scope | th:scrolling |
th:size | th:sizes | th:span |
th:spellcheck | th:src | th:srclang |
th:standby | th:start | th:step |
th:style | th:summary | th:tabindex |
th:target | th:title | th:type |
th:usemap | th:value | th:valuetype |
th:vspace | th:width | th:wrap |
th:xmlbase | th:xmllang | th:xmlspace |
4. 사용 예제
[Controller 소스]
@Controller
public class UserTestController {
@GetMapping("/users")
public String getUserList(Model model) {
List<User> users = new ArrayList<>();
for(int i=0;i<3;i++) {
users.add(new User("kkaok"+i, "테스트"+i, "web") );
}
User user = new User("테스트ID", "테스터", "web") ;
model.addAttribute("user", user);
model.addAttribute("users", users);
model.addAttribute("today", new Date());
model.addAttribute("content", "<div><span style='font-size:20px'>Hello World</span></div>");
return "users";
}
}
[HTML 소스]
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Thymeleaf 예제</title>
<!-- Link 예제 -->
<script th:src="@{/assets/vendor/jquery/jquery.js}"></script>
</head>
<body>
<h1>Collection 객체 each 예제</h1>
<p th:each="user : ${users}" th:text="${user.name}"></p>
<h1>Utility Objects 예제</h1>
<p>#calendars <br>Today is: <span th:text="${#calendars.format(today,'yyyy-MM-dd')}">2019-02-15</span></p>
<p>#arrays <br>user count is <span th:text="${#arrays.length(users)}"></span>.</p>
<h1>객체 예제</h1>
<p th:text="${user.name}">default</p>
<p>[[${user.name}]]</p>
<h1>th:text 예제</h1>
<p th:text="${content}">default value</p>
<h1>th:utext(Html) 예제</h1>
<p th:utext="${content}">default value</p>
<h1>th:with 예제 : 변수 선언</h1>
<p th:with="authType = ${user.authType}+' Type'" th:text="${authType}"></p>
<h1>th:if 예제</h1>
<p th:if="${user.authType}=='web'" th:text="${user.authType}"></p>
<h1>th:unless 예제</h1>
<p th:unless="${user.authType}=='facebook'" th:text="'not '+ ${user.authType}"></p>
<h1>script 예제</h1>
<p><span id="scriptTest"></span></p>
<script>
// script에서 값을 받을 때
var userId = '[[${user.userId}]]';
console.log(userId);
$("#scriptTest").html(userId);
</script>
</body>
</html>
REFERENCE
'Spring Boot' 카테고리의 다른 글
[Spring Boot] JUnit을 활용한 테스트 코드 작성(1) (0) | 2020.05.03 |
---|---|
[Spring Boot] 의존성 주입 생성자 주입 (0) | 2020.05.03 |
[Spring Boot] 스프링부트 jenkins, docker, github사용하여 배포 (0) | 2020.03.01 |
[Spring Boot] 인텔리제이(intellij) lombok 설정 (0) | 2020.02.03 |
Spring Boot 자동 설정 (0) | 2020.01.22 |