Thymeleaf
타임리프란, 자바 기반의 템플릿 엔진으로 MVC 패턴에 적합하게 설계된 템플릿 엔진이다.
타임리프는 View Template이라고도 불리는데, 이는 컨트롤러가 전달하는 데이터를 이용하여 동적으로 화면을 구성할 수 있게 해준다.
JSP vs Thymeleaf
jsp를 사용한 웹 어플리케이션 제작시, 자바 프로젝트 파일은 필연적으로 war 파일로 만들어진다. 그리고 war 파일은 jar 파일에 비해, jsp의 해석과 관련된 모든 패키지들이 포함되며 무거운 구조가 되었다.
타임리프는 HTML을 기반으로 하기에 굳이 war로 말 필요 없이 jar 파일로 말아서 사용할 수 있고,
덕분에 war이라는 무거운 구조에서 벗어날 수 있게 되었다.
활용법
스프링 부트을 기준으로 사용법은 web.xml에 다음 디펜던시를 추가하는 것이다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
그리고 application.properties에서 세부 설정을 할 수 있다.
#cache가 false일 경우 html 수정 시 재가동할 필요 없이 웹에서 확인 가능. (개발용)
spring.thymeleaf.cache=false
#타임리프 폴더의 prefix와 suffix
spring.thymeleaf.prefix=classpath:templates/
spring.thymeleaf.suffix=.html
#템플릿을 렌더링하기 전 템플릿의 존재 여부 확인
spring.thymeleaf.check-template=true
#템플릿 위치의 존재 여부 확인
spring.thymeleaf.check-template-location=true
#웹 프레임워크에 대한 타임리프 보기 확인 활성화 여부
spring.thymeleaf.enabled=true
#springEL 컴파일러 활성화
spring.thymeleaf.enable-spring-el-compiler=false
#템플릿 파일 인코딩 설정
spring.thymeleaf.encoding=UTF-8
#확인에서 제외해야 하는 쉼표로 구분된 보기 이름(패턴 허용) 목록
spring.thymeleaf.excluded-view-names=
#템플릿에 적용할 템플릿 모드
spring.thymeleaf.mode=HTML
#최대 청크 크기가 설정되었을 때 CHUNKED 모드에서 실행되는 유일한 보기 이름(패턴 허용)의 쉼표로 구분된 목록
spring.thymeleaf.reactive.chunked-mode-view-names=
#최대 청크 크기가 설정되어 있더라도 FULL 모드에서 실행되어야 하는 쉼표로 구분된 보기 이름(패턴 허용) 목록
spring.thymeleaf.reactive.full-mode-view-names=
#응답에 쓰는 데 사용되는 데이터 버퍼의 최대 크기
spring.thymeleaf.reactive.max-chunk-size=0B
#보기 기술이 지원하는 미디어 유형
spring.thymeleaf.reactive.media-types=
#체크박스의 마커 역할을 하는 숨겨진 양식 입력이 체크박스 요소 자체보다 먼저 렌더링되어야 하는지 여부
spring.thymeleaf.render-hidden-markers-before-checkboxes=false
#HTTP 응답에 기록된 Content-Type 값
spring.thymeleaf.servlet.content-type=text/html
#Thymeleaf가 가능한 한 빨리 부분 출력 쓰기를 시작해야 하는지 아니면 템플릿 처리가 완료될 때까지 버퍼링해야 하는지 여부
spring.thymeleaf.servlet.produce-partial-output-while-processing=true
#체인에서 템플릿 해석기의 순서
spring.thymeleaf.template-resolver-order=
#확인할 수 있는 보기 이름(패턴 허용)의 쉼표로 구분된 목록
spring.thymeleaf.view-names=
출처: https://frontbackend.com/thymeleaf/thymeleaf-default-spring-boot-application-properties
활용법 : 기본 변수
기본적으로 ModelAndView를 사용하면 addObject 함수를 사용하여 (키, 값) 으로 넣어서 데이터를 전송할 수 있다.
@Controller
public class test {
@RequestMapping(value = {"/test"}, method= RequestMethod.GET})
public ModelAndView test() {
ModelAndView mav = new ModelAndView("test"); // prefix, suffix와 결합되어 classpath:template/test.html 이 된다.
String strSample = "test";
int intSample = 0;
mav.addObject("strSample", strSample); //키-값 쌍으로 삽입
mav.addObject("intSample", intSample);
return mav;
}
}
그리고 HTML에서는 th:<type> = "${키값}" 안에서 사용이 가능하다.
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<table>
<tr> <th colspan = "2"> PrimitiveTypeSamples </th></tr>
<tr> <td> <span th:text = "${intSample}">intSample</span> </td> </tr>
<tr> <td> <span th:text = "${strSample}">strSample</span> </td> </tr>
</table>
</body>
</html>
활용법 : 자료구조
기본 변수 외에도 List, Map과 같은 자료구조들도 전송 및 활용이 가능하다.
//맵
Map<String, String> mapSample = new HashMap<String, String>();
mapSample.put("key1", "val1");
mapSample.put("key2", "val2");
//리스트
List<String> listSample = new ArrayList<String>();
listSample.add("list1");
listSample.add("list2");
mav.addObject("mapSample", mapSample);
mav.addObject("listSample", listSample);
마찬가지로 HTML에서는 th:<type> = "${키값}" 으로 사용이 가능하다.
여기서 리스트와 맵에서 각 객체를 뽑아올 때는 아래와 같이 for-each 구문과 비슷하게 사용을 한다.
또한 자료구조에는 .empty 와 th:if 문을 활용해 각 자료구조가 비었는지를 사전에 확인할 수 있다.
여기서 else로는 unless를 사용하는데, else와 완전히 같지는 않고, 조건문 안의 내용이 false 일 경우 실행되게 된다.
<tr> <th colspan = "2"> MapSamples </th> </tr>
<tr th:if="${mapSample.empty}">
<th colspan = "2"> empty list </th>
</tr>
<tr th:unless="${mapSample.empty}" th:each="sample : ${mapSample}">
<td> <span th:text = "${sample.key}"> key </span> </td>
<td> <span th:text = "${sample.value}"> value </span> </td>
</tr>
<tr> <th colspan = "2"> ListSamples </th> <tr>
<tr th:if="${listSample.empty}">
<th colspan = "2"> empty list </th>
</tr>
<tr th:unless="${listSample.empty}" th:each="sample : ${listSample}">
<td> <span th:text = "${sample}" colspan = "2">sample</span></td>
</tr>
굳이 for-each를 사용하지 않고 Map 내의 Value를 가져오고 싶다면 ${mapSample['key1']} 과 같이 가져올 수 있다.
활용법 : Object
id, name 라는 두 개의 String 멤버 변수를 가진 TestObject 클래스를 만들어서 활용해보자.
메인에 들어갈 추가 코드는 다음과 같다.
//객체
TestObject objectSample = new TestObject("id", "name");
//객체 리스트
List<TestObject> objectListSample = new ArrayList<>();
objectListSample.add(new TestObject("id1", "name1"));
objectListSample.add(new TestObject("id2", "name2"));
mav.addObject("objectSample", objectSample);
mav.addObject("objectListSample", objectListSample);
그리고 HTML에는 다음과 같이 들어가게 된다. 사용법은 앞에서 설명한 내용과 같다.
단 여기서 주의할 점은 getId() 와 같은 함수가 아닌 id 라는 변수를 직접적으로 가져오는 듯한 문법을 사용한다. 만약 멤버 변수가 public이라면 가져올 수 있으나, 당연하게도 대부분의 변수들은 private으로 선언이 되어있을 것이다.
하지만 걱정할 것이 없는게, public으로 선언된 getter 함수가 존재한다면, 아래와 같은 방식으로도 타임리프 내에서 객체의 멤버 변수에 접근이 얼마든지 가능해진다.
즉, 변수를 public으로 할 게 아니라면 타임리프 내에서 변수 접근을 위해 getter 함수가 필요하다.
<tr> <th colspan = "2"> ObjectSamples </th> </tr>
<tr>
<td> <span th:text = "${objectSample.id}"> id </span> </td>
<td> <span th:text = "${objectSample.name}"> name </span> </td>
</tr>
<tr> <th colspan = "2"> ObjectListSamples </th> </tr>
<tr th:if="${objectListSample.empty}">
<th colspan = "2"> empty list </th>
</tr>
<tr th:unless="${objectListSample.empty}" th:each="sample : ${objectListSample}">
<td> <span th:text = "${sample.id}"> id </span> </td>
<td> <span th:text = "${sample.name}"> name </span> </td>
</tr>
활옹법 : 여러 변수 사용
Hello 와 World 를 서로 다른 변수에 담아서 보내주고 한 문장 속에서 보여주기 위해서는 어떻게 해야할까?
혹은 한 변수에 추가적으로 어떤 문구를 추가해서 사용하고 싶으면 어떻게 해야할까?
String str1 = "Hello";
String str2 = "World";
mav.addObject("str1", str1);
mav.addObject("str2", str2);
생각만으로는 그냥 th:text="${변수1} ${변수2}" 이렇게 보내주면 될 것 같지만, 아쉽게도 org.thymeleaf.exceptions.TemplateProcessingException: Could not parse as expression
이 발생하게 된다.
또한 th:text="${변수} abcd" 와 같이 변수 + 문자열의 조합도 같은 오류를 발생시킨다.
이에 대한 해결법은 간단하다. | | 안에 감싸서 사용하면 여러 개의 변수들을 사용할 수 있다.
또한 | | 안에는 변수 뿐 아니라 일반 문자와 띄어쓰기 등을 함께 사용할 수 있다.
<span th:text="|${str1}${str2}|"></span>
<span th:text="|${str1} everyone. Welcome to ${str2}|"></span>
활용법 : 자바 스크립트
자바 스크립트 내에서 HTML과 같이 "${변수명}"은 사용할 수 없다.
자바 스크립트에서 타임리프 변수를 사용하는 법은 [[ ]] 안에 넣어서 사용하는 것이다.
물론 th:text="${str1} ${str2}" 가 안되는 것처럼, 같은 [[ ]] 안에 넣을 수는 없고,
각 변수를 [[ ]] 안에 넣어서 사용하면 가져올 수 있다.
<script th:inline="javascript">
console.log([[${str1}]]) //Hello
console.log([[${str1}]] + ' ' + [[${str2}]]) //Hello World
listSample = [[${listSample}]] // ['list1', 'list2']
for(i in listSample) console.log(listSample[i])
objectSample = [[${objectSample}]] // {id : id, name : name}
console.log(objectSample.id) //id
</script>
APPENDIX#1 환경변수 불러오기
application.properties 등에 설정된 환경변수는 프로그램 전반에서 사용된다. 그리고 이는 UI내에서도 사용될 수 있다.
만약 Thymeleaf HTML 내에서 해당 변수를 불러와야 한다면 아래와 같이 불러올 수 있다.
*HTML 내에서
${@environment.getProperty('환경변수명')}
*JS 내에서
/*[[${@environment.getProperty('환경변수명')}]]*/
APPENDIX#2 세션 내 데이터 불러오기
사용자 명을 가져와서 출력하는 등 세션 내 데이터를 가져오는 방법은 아래와 같다.
*HTML 내에서
${session.변수명}
*JS 내에서
[[${session.변수명}]]
'실습 > 리눅스 서버 + 스프링 부트' 카테고리의 다른 글
Spring Security (0) | 2021.11.07 |
---|---|
HAProxy를 활용한 IFrame 활성화 (0) | 2021.09.26 |
09. MariaDB CRUD_UI (0) | 2021.09.18 |
08. HAProxy (0) | 2021.05.30 |
07. Kafka_Pub&Con (0) | 2021.05.30 |