김동형수 개발기

Spring MVC 4에 Thymeleaf 3 적용하기 본문

Spring

Spring MVC 4에 Thymeleaf 3 적용하기

김동형수 2019. 12. 26. 16:58

Framework : Spring MVC 4

Template : Thymeleaf 3

Layout : LayoutDialect 2

 

우선 pom.xml에 Thymeleaf 와 layout의 의존성 추가를 합니다.

pom.xml

...
        
		<!-- Thymeleaf : template engine -->
		<dependency>
			<groupId>org.thymeleaf</groupId>
			<artifactId>thymeleaf</artifactId>
			<version>3.0.9.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.thymeleaf</groupId>
			<artifactId>thymeleaf-spring4</artifactId>
			<version>3.0.9.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>nz.net.ultraq.thymeleaf</groupId>
			<artifactId>thymeleaf-layout-dialect</artifactId>
			<version>2.3.0</version>
		</dependency>
        
...

그리고 DispatcherServlet에 Thymeleaf의 Bean설정을 추가합니다.

 

제 경우에는 Spring MVC 생성 후 dispatcher 설정 xml파일의 이름을 변경하지 않았기 때문에 servlet-context.xml에다가 해당 정보를 추가했습니다.

 

DispatcherServlet

...

	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
		<beans:property name="prefix" value="/WEB-INF/views/" /> 
		<beans:property name="suffix" value=".jsp" />
		<!-- thymeleaf 가 먼저 처리될 수 있도록 순번을 1보다 높게 준다. -->
		<beans:property name="order" value="2" />
	</beans:bean> 

	<beans:bean id="templateResolver" class="org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".html" />
		<beans:property name="templateMode" value="HTML" />
		<beans:property name="characterEncoding" value="UTF-8" />
		<beans:property name="cacheable" value="false" />
	</beans:bean>	
	
	<beans:bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
		<beans:property name="templateResolver" ref="templateResolver" />
		<beans:property name="additionalDialects">
			<beans:set>
			  <beans:bean class="nz.net.ultraq.thymeleaf.LayoutDialect" />
			</beans:set>
		</beans:property>
	</beans:bean>	
	
	<beans:bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
		<beans:property name="templateEngine" ref="templateEngine" />
		<beans:property name="characterEncoding" value="UTF-8" />
		<beans:property name="order" value="1" />
	</beans:bean>
    
...    

 

이로서 Thymeleaf를 사용하기위한 최소 설정은 끝났습니다.

 


이제 실제 템플릿을 구정할 레이아웃과 그 중의 요소인 header, footer 파일을 작성해봅시다.

 

위에서 설정한 DispatcherServlet 의 templateResolver bean의 prefix 프로퍼티를 root path삼아서 템플릿 관련 파일들을 생성해보았다.


layout

<!DOCTYPE html>
<html lang="ko" 
    xmlns:th="http://www.thymeleaf.org"
    xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">

<head>

<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Kim ddongs sample</title>    

<!--[if lt IE 9]>
  <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
  <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
  <![endif]-->

<!-- 
import sample

<script th:src="@{/abc/a.js}"></script> 
=> <script src="/abc/a.js"></script>

<link rel="stylesheet" th:href="@{/abc/a.css}">
=> <link rel="stylesheet" href="/abc/a.css">
 -->
</head>

<!-- body 태그 내부의 header 를 담당하는 부분이다. -->
<header th:replace="structure/header/type1 :: header"></header>

<!-- 아래 div가 컨트롤러에 의해 교체되는 content 영역이다. -->
<div layout:fragment="content"></div>

<!-- body 태그 내부의 footer 를 담당하는 부분이다. -->
<footer th:replace="structure/footer/type1 :: footer"></footer>

</html>
<!--
/webapp/WEB-INF/views/structure/layout/type1.html
-->

header

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

<header id="header" class="main-header" th:fragment="header">

헤더

</header>

</html>
<!--  
/webapp/WEB-INF/views/structure/header/type1.html
-->

footer

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

  <footer id="footer" class="main-footer" th:fragment="footer">
      풋터
  </footer>

</html>

<!-- 
/webapp/WEB-INF/views/structure/footer/type1.html
-->

layout에 등장하는 thymeleaf attribute인 th:replace를 통해서 header와 footer를 대체하는데 jsp의 include와 동일한 역할을 수행하는 것으로 보여집니다.

 

 

위에서 작성한 템플릿 요소들을 적용해보도록 하겠습니다.

 

우선 컨텐츠는 템플릿 요소와 구분을 위해서 /WEB-INF/views/content 로 시작하는 경로를 사용합니다.

내용은 아래와 같습니다.


home.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
    xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
    data-layout-decorate="~{structure/layout/type1}"
    >

<div layout:fragment="content">

  컨텐츠

</div>

</html>

<!--
/webapp/WEB-INF/views/content/home.html
-->

컨트롤러는 이클립스에서 Spring MVC 프로젝트를 생성하면 기본으로 제공되는 HomeController.java를 조금 수정해서 사용했습니다. content폴더 하위에 home.html이 위치하기 때문에 뷰의 상대경로인 content/home를 반환해줍니다.

 

data-layout-decorate="~{structure/layout/type1}" 이 부분이 해당 뷰에서 사용될 템플릿 페이지를 설정하는 부분입니다.

 


Finish

프로젝트를 진행하면서 title, jsp include 그리고 thymeleaf 총 3가지를 이용해서 layout 설정을 했었는데요.

초기 설정을 할때 이외에는 페이지 작성할 때 그렇게 많은 차이를 체감하지는 못하는 것 같습니다.

 

결론은 작업하시기 편한 방법으로 하시면 될 것 같습니다..

 

이상입니다. 아래 제 git에 샘플소스가 있으니 필요하시면 참고 부탁드립니다.

 

감사합니다.


Sample Code

https://github.com/kim-ddongs/spring4-thymeleaf3-layout2


Reference

https://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html
https://www.hanumoka.net/2018/08/04/spring-20180804-spring4-thymeleaf3-thymeleaf-layout/

 

Comments