간단한 CRUD를 구현하다가 org.thymeleaf.exceptions.TemplateProcessingException 에러를 너무 많이 겪어서 타임리프에 대해 잠깐 공부하기로 했다. (위 에러는 타임리프 문법을 잘못 쓰는 등의 이유로 특정 url을 찾지 못하거나 파싱 에러가 나는 경우에 자주 나는 에러이다.)
Thymeleaf란?
'템플릿 엔진'의 일종. html 태그에 속성을 추가해 페이지에 동적으로 값을 추가하거나 처리할 수 있다.
타임리프를 통해 속성을 대체할 수 있는데, 아래 예제를 살펴보자.
<input type="text"
value="test"
th:value="${item}"> <!--th:value 타임리프의 문법을 이용해 value 설정-->
input 태그는 th:value를 통해 item이라는 변수에 값이 존재하면 해당 값을 세팅해준다.
만약 item이 존재하지 않으면 value="test"를 통해 "test"라는 문자열을 세팅해준다.
(= th:xxx가 붙은 부분은 서버 사이드에서 렌더링 되어 기존 것을 대체하고, th:xxx이 없으면 xxx 속성이 그대로 사용)
타임리프를 통해 렌더링 된 html 페이지를 열어도 웹 브라우저는 th: 속성을 알지 못한다.
🔻 템플릿 엔진이란?
: 지정된 템플릿 양식과 데이터가 합쳐져 html 문서를 출력하는 소프트웨어.
크게 서버 템플릿 엔진과 클라이언트 템플릿 엔진으로 나뉘는데, 타임리프는 전자에 해당하니 이에 대해서만 간단히 설명하겠다.
서버에서 DB 또는 API 등을 통해 가져온 데이터를 미리 정의된 템플릿에 넣어 html을 그려내 클라이언트에 전달해준다. 즉, html 코드에서 고정적으로 사용되는 부분은 템플릿으로 만들어두고 동적으로 생성되는 부분만 템플릿 특정 장소에 끼워넣는 방식으로 동작할 수 있게 해준다.
템플릿 엔진의 장점
- 코드 양 ↓
- 재사용성 ↑
- 유지보수에 용이
여러 서버 템플릿 엔진의 특징
- JSP: 스프링 부트에서 비권장
- Velocity: 스프링 부트에서 비권장
- Freemarker: 템플릿 엔진으로서 기능이 너무 다양함. 숙련도 낮은 경우 비즈니스 로직이 추가됨.
- Thymeleaf: 스프링에서 권장. 문법이 어려움.
- Mustache: 심플하고 서버, 클라 모두 사용 가능.
Thymeleaf 사용하기
thymeleaf 뷰 템플릿을 사용하기 위해서는 ThymeleafViewResolver를 등록해야 한다.
아래 라이브러리를 추가하면 Spring이 위 작업을 자동화 해준다.
Gradle - build.gradle
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
Maven - pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
위 설정을 추가 후 빌드하면 application.properties에 아래 코드가 자동으로 추가된다.
디폴트 설정을 원하지 않는다면 직접 수정해도 된다.
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
타임리프를 사용할 html 파일에 다음과 같이 태그를 수정해준다.
<html xmlns:th="http://www.thymeleaf.org">
타임리프를 사용할 준비가 끝났다.
이제 타임리프의 문법을 간단히 살펴보자.
Thymeleaf 문법
대부분의 html 속성을 th:xxx 로 변경할 수 있다.
ex: th:text="${변수명}"
표현 | 설명 | 예제 |
@{ ... } | URL 링크 표현식 | th:href="@{/css/bootstrap.min.css}" th:href="@{/{itemId}/edit(itemId=${item.id})}" |
| ... | | 리터럴 대체 | th:text="|Hi ${user.name}!|" (= th:text="'Hi '+${user.name}+'!'" |
${ ... } | 변수 | th:text=${user.name} |
th:each | 반복 출력 | <tr th:each="item: ${items}"> <td th:text="${item.price}">100</td> </tr> |
*{ ... } | 선택 변수 | <tr th:object="${items}"> <td th:text="*{price}">100</td> </tr> |
#{ ... } | 메시지. properties 같은 외부 자원에서 코드에 해당하는 문자열 get. | th:text="#{member.register}" |
더 많은 예제
소스 코드를 통해 예제를 살펴보고 싶은 경우 아래 레포지토리에서 참고하면 좋을 것 같다.
상품 서비스의 CRUD를 간단하게 구현하였다.
👉 https://github.com/yeon-06/inflearnSpring/tree/master/mvc1-3
참고
- inflearn - 김영한님의 '스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술'
- 템플릿 엔진: https://usefultoknow.tistory.com/entry/%ED%85%9C%ED%94%8C%EB%A6%BF-%EC%97%94%EC%A7%84Template-Engine-%EC%9D%B4%EB%9E%80
- 타임리프 문법: https://jongminlee0.github.io/2020/03/12/thymeleaf/
'Develop > Spring+JPA' 카테고리의 다른 글
[Spring/MariaDB] 연동 시 자주 발생하는 오류 (0) | 2021.12.26 |
---|---|
Entity vs DTO vs VO (3) | 2021.11.23 |
[Spring] HTTP 메시지 컨버터 (0) | 2021.10.10 |
[Spring] HTTP 응답 (0) | 2021.08.11 |
[Spring] http 요청 데이터 조회 (0) | 2021.08.09 |