Thymeleaf는 자바 템플릿 엔진입니다. 템플릿이 HTML로 만들어지고 HTML 엘리먼트의 속성으로 제어하기 때문에 서버를 실행하지 않고 브라우저에서 내용을 확인할 수 있으며, 템플릿 자체가 의미 있는 결과물로 관리될 수 있는 장점이 있습니다. 

예제를 통해서 이메일 템플릿 정보를 String으로 얻는 과정을  알아보겠습니다. 먼저 Maven을 통해서 Thymeleaf를 추가합니다.

...
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring4</artifactId>
    <version>3.0.3.RELEASE</version>
</dependency>
...


이메일 템플릿은 HTML을 얻기 위한 정보니까 경로는 src/main/resources/mail/html로 지정하고 파일명은 email-template.html로 하나 생성합니다.

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title th:remove="all">이메일 기본 템플릿</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p>안녕하세요. <strong th:text="${name}">홍길동</strong>님의 구매안내 메일입니다.</p>
<h3>구매 내역</h3>
<table th:remove="all-but-first">
    <tr th:each="orderItem : ${orderItemList}" th:with="result=${orderItem.price}">
        <td style="background: #efefef; padding: 10px;">
            <span th:text="${orderItem.name}" th:remove="tag">치약</span>
        </td>
        <td>
            <span th:text="${#numbers.formatCurrency(orderItem.price)}"
                  th:remove="tag">₩3,600
            </span>원
        </td>
    </tr>
    <tr>
        <td style="background: #efefef; padding: 10px;">
            <span th:remove="tag">참치</span>
        </td>
        <td>₩4,300원</td>
    </tr>
</table>
<p>
    전체 결제금액
    <span th:text="${#numbers.formatCurrency(#aggregates.sum(orderItemList.![price]))}"
          th:remove="tag">₩7,900
    </span>원
</p>
<p>
    구매일
    <span th:text="${#dates.format(orderDate, 'yyyy-MM-dd HH:mm:ss')}">
        2017-01-30 23:59:59
    </span>
</p>
<p>감사합니다.</p>
</body>
</html>


템플릿 자체가 HTML이기 때문에 생성한 email-template.html를 브라우저에서 실행하면 내용을 확인할 수 있습니다. 엘리먼트에 있는 th로 시작하는 속성들은 Thymeleaf를 통해서 호출하면 처리되는 내용들입니다. 처음에는 약간 복잡하게 느껴질 수도 있지만 생각보다 간단하며 Intellij에서 Thymeleaf를 지원하기 때문에 템플릿 작성도 한결 수월합니다.  

HTML을 그냥 실행하면 아래 캡처 이미지처럼 나오는 것을 확인할 수 있습니다.  이 템플릿이 실행되면 어떻게 노출될지 미리 확인할 수 있기 때문에 매력적이라고 할 수 있습니다.



Thymeleaf를 이용해서 템플릿을 조회하기 위해서 TemplateEngine를 정의하고 templateResolver로 ClassLoaderTemplateResolver로 지정합니다. 특별한 내용은 없고 설정은 Spring ViewResolver와 비슷한 것을 알 수 있습니다.
@Configuration
public class ThymeleafConfig {

	private static final String EMAIL_TEMPLATE_ENCODING = "UTF-8";

	@Bean
	public TemplateEngine emailTemplateEngine() {
		final SpringTemplateEngine templateEngine = new SpringTemplateEngine();
		templateEngine.addTemplateResolver(htmlTemplateResolver());
		return templateEngine;
	}

	private ITemplateResolver htmlTemplateResolver() {
		final ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
		templateResolver.setOrder(1);
		templateResolver.setResolvablePatterns(Collections.singleton("html/*"));
		templateResolver.setPrefix("/mail/");
		templateResolver.setSuffix(".html");
		templateResolver.setTemplateMode(TemplateMode.HTML);
		templateResolver.setCharacterEncoding(EMAIL_TEMPLATE_ENCODING);
		templateResolver.setCacheable(false);
		return templateResolver;
	}
}


Context를 통해서 템플릿에 필요한 변수를 key/value 형식으로 전달합니다. ThymeleafConfig에서 정의한 TemplateEngine.process()를 통해서 email-template.html과 Context 정보를 전달하면 템플릿 처리 결과를 확인할 수 있습니다.

@Slf4j
public class MailTemplateLoader {

	public static void main(String[] args) {
		ApplicationContext context =
				new AnnotationConfigApplicationContext(ThymeleafConfig.class);

		List orderItemList = Arrays.asList(
				new Item("생수", 12000),
				new Item("티슈", 3500),
				new Item("맥주", 9800));

		final Context ctx = new Context(Locale.KOREA);
		ctx.setVariable("name", "Brady");
		ctx.setVariable("orderDate", new Date());
		ctx.setVariable("orderItemList", orderItemList);

		TemplateEngine templateEngine = context.getBean(TemplateEngine.class);
		final String htmlContent = templateEngine.process("html/email-template", ctx);

		log.info(htmlContent);
	}

	@Data
	@AllArgsConstructor
	public static class Item {
		private String name;
		private Integer price;
	}

}


실행된 결과 html을 브라우저에서 실행한 화면입니다. 단순 html 일 때 확인한 내용과 템플릿 처리 이후에 내용의 차이는 Context를 통해서 전달한 변수에 의해 달라질 뿐 기대했던 템플릿 내용대로 나온 것을 확인할 수 있습니다.



참고 - http://www.thymeleaf.org/doc/articles/springmail.html


+ Recent posts