0. 템플릿 엔진
- 템플릿 양식과 데이터가 합쳐져 HTML 문서를 출력하는 소프트웨어
- ⇒ view (HTML) 와 데이터 로직 코드 (DB Connection) 을 분리!
- 렌더링 주체에 따라 서버 사이드 템플릿 엔진, 클라이언트 사이드 템플릿 엔진으로 나뉨
0-1. 서버 사이드 템플릿 엔진
- 서버에서 구동되는 템플릿 엔진
- 서버에서 데이터를 미리 정의된 템플릿에 넣음 → HTML 생성해 클라이언트에 전달
- 대표적) JSP, Thymeleaf, Velocity, Freemarker 등
0-2. 클라이언트 사이드 템플릿 엔진
- 브라우저 위에서 동작하는 템플릿 엔진
- 서버는 데이터만 전달 (JSON 등) → 클라이언트가 데이터를 템플릿에 넣어 화면 생성
- 대표적) Mustache, Handlebars 등
1. Thymeleaf
- 자바 템플릿 엔진, 서버 사이드 템플릿 엔진
- HTML 태그 기반 → th:속성명 추가해 동적 view 생성
- 스프링과 자연스럽게 통합되어 다양한 기능 사용 가능 ⇒ 스프링 부트에서 사용 권장
1-2. 사용 방법
1-2-1. 라이브러리 추가
- 의존 라이브러리 추가 (build.gradle)
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
- 의존 라이브러리 추가 (pom.xml)
<dependency>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
1-2-2. HTML에 추가
- HTML 문서의 시작 부분에 XML 네임스페이스 정의
<html xmlns:th="http://www.thymeleaf.org">
2. 기본 문법
2-1. 변수 표현식
- 컨트롤러에서 전달된 변수 등을 HTML 파일에서 받음
- ${변수이름}
<p th:text="${username}"></p>
2-2. 계산 표현식
- 수학적 계산이나 메서드 호출 등을 통해 값을 계산
- ${계산식}
<p th:text="${user.age + 1}">내년 나이</p>
2-3. 선택 표현식
- 자바의 삼항 연산자와 유사
- ${조건식 ? 참일때 로직 : 거짓일때 로직}
<p th:text="${user.age >= 20 ? '성인입니다.' : '미성년자입니다.'}"></p>
2-4. 호출 표현식
- 컨트롤러로 넘어온 객체의 메서드나 속성을 호출
- ${객체이름.메서드이름()} / ${객체이름.속성이름}
<p th:text="${user.getFullAddress()}">주소</p>
2-5. 조건문
- 조건의 참/거짓 여부에 따라 HTML 요소의 렌더링 여부 제어
- th:if / th:unless
<div th:if="${user.name == null}">
이름을 설정해주세요!
</div>
<div th:unless="${user.name != null}">
${user.name} 님 안녕하세요!
</div>
2-6. 반복문
- 컬렉션(리스트, 배열 등)의 각 요소를 반복
- th:each
<ul>
<li th:each="user : ${userList}" th:text="${user.name}">유저 이름</li>
</ul>
📌 문자열 관련
- 문자열 합치기 : +
- 리터럴 대체 : |
- 아래의 두 요소는 같은 결과를 출력함
<div th:text="'hello ' + ${user.name} + '!'"></div>
<div th:text="|hello ${user.name}!|"></div>
- 날짜 형식화
<p th:text="'오늘 날짜는 ' + ${#dates.format(currentDate, 'yyyy년 MM월 dd일')} + '입니다.'"></p>
2-7. 속성 바인딩
2-7-1. 텍스트
- th:text : 변수, 객체 등의 값을 출력
<p th:text="${username}"></p>
- [[ ${변수명} ]] : th:text 사용 없이 직접 변수 출력
<p>[[${username}]]</p>
- th:utext
- 위의 두 방법은 HTML에서 String으로 인식됨
- 넘어온 문자열을 “태그” 로써 사용 가능
<!-- 넘어온 문자열이 "안녕하세요<br/>홍길동입니다." 일 때 -->
<div th:text="${string}"></div> <!-- "안녕하세요<br/>홍길동입니다." 그대로 출력됨 -->
<div th:utext="${string}"></div>
<!-- "안녕하세요
홍길동입니다." 태그 반영되어 출력됨 -->
2-7-2. URL 이동 관련
- 요소(버튼, 텍스트 등)에 다음 URL을 지정
- th:href
- 링크 URL 표현식 : @{…}
<a th:href="@{/home}">홈으로 가기</a>
📌 th:href → 파라미터 전달
- Query String으로 전달 (ex. /home?name=”홍길동”&age=21)
<a th:href=”@{/home(name=${user.name}, age=${user.age})}”></a>
- Path Variable 로 전달 (ex. /home/홍길동/21)
<a th:href=”@{/main/{name}/{age} (name=${user.name}, age=${user.age})}”></a>
2-7-3. 경로 관련
- 이미지, 자바 스크립트 등의 경로를 동적으로 설정
- th:src
<img th:src="@{${user.profileImage}}" alt="프로필 이미지"/>
2-8. 템플릿 조각
- 재사용 가능한 HTML 조각을 정의하고 호출
- layout, header, bodyHeader, footer 등
- th:fragment : 템플릿 조각 정의
- th:replace : 템플릿 조각 호출 (대체)
- th:insert : 템플릿 조각 삽입
<!-- header 정의 -->
<header th:fragment="header">
<!-- header 호출 -->
<head th:replace="~{header :: header}"></head>