Spring Boot

DAY 85 - Thymeleaf (2024.11.06)

summ.n 2024. 11. 6. 17:42

Thymeleaf - *.html - 응답페이지 (요청페이지 X) 

JSP - *.jsp

 

Spring Boot는 jsp를 없애고있으므로 타임리프가 깔리고 들어간다.

 

main에 리액트를 넣어본적은 있다.

근데 여기에 jsp파일을 넣어보고싶으면? 

src

   main

        webapp

             WEB-INF

이런식으로 구조를 만든다음에 (폴더 2개 직접 생성) jsp 파일 만들면 된다.

근데 스프링사에서 jsp 쓰지말라고 죽였는데 강압적으로 넣을 수 있다. ( 추천하지는 않는다. )

 

우리는 이 부분에 

src

   main

        React가 껴들어올거다

리액트는 3000포트이고

스프링부트는 8080이므로 서버를 2개 띄우기가 귀찮으므로

리액트 3000포트를 8080포트로 포워딩할 것이다.

 

타임리프는 기본적으로 템플릿을 찾으므로 우리는 템플릿베이직 안에 만든 것이다.


index.html

<p><a href="text_basic">text_basic.html</a></p>


ThymeleafController.java

	@GetMapping(value="text_basic")
	public String text_basic(ModelMap modelMap) {
		modelMap.put("data", "Spring bOOT");
		return "basic/text_basic";
	}

text-basic.html

<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>컨텐츠에 데이터 출력하기</h1>
<ul>
	<li>th:text 사용 <span th:text="">ㅋㅋㅋ</span></li>
</ul>
</body>
</html>

 

 

span 태그 안에 서버로부터 가져온 data를 삽입하겠다.

<li>th:text 사용 <span th:text="${data}">ㅋㅋㅋ</span></li>

 


컨텐츠 안에서 직접 출력

<li>컨텐츠 안에서 직접 출력 = [[${data}]]</li>


전체코드

<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>컨텐츠에 데이터 출력하기</h1>
<ul>
	<li>th:text 사용 <span th:text="${data}">ㅋㅋㅋ</span></li>
	<li>컨텐츠 안에서 직접 출력 = [[${data}]]</li>
</ul>
</body>
</html>

index.html

<p><a href="attribute">attribute.html</a></p>


ThymeleafController.java

	@GetMapping(value="attribute")
	public String attribute(ModelMap modelMap) {
		modelMap.put("data", "Spring Boot");
		return "basic/attribute";
	}

attribute.html

<input type="text" name="mock" />

input 태그 / 태그 안에 들어있는 거를 속성이라고 한다.

 

<input type="text" name="mock" th:name="userName"/>

속성이 바뀌는 것을 알 수 있다.


<!-- -->

HTML 주석은 브라우저에는 안 보이나 내부적으로는 실행을 한다.

<input type="text" name="mock" th:name="userName"/> <!-- <input type="text" name="userName" > -->

 

 

타임리프 주석으로 바꾸면 화면에 안찍히는 것을 확인할 수 있다 !

<input type="text" name="mock" th:name="userName"/> <!--/*== <input type="text" name="userName" > */-->


attrappend - 추가 (뒤로 추가가 된다.)

<input type="text" class="text" th:attrappend="class= ' large'" />


attrprepend - 추가( 앞으로 추가가 된다.)

<input type="text" class="text" th:attrprepend="class= 'large '" />


classappend - 추가(무조건 앞으로 된다.)

<input type="text" class="text" th:classappend="large" />


checked 처리

<input type="checkbox" name="active" th:checked="true" />사과

 

 

<input type="checkbox" name="active" th:checked="false" />딸기

 

 

<input type="checkbox" name="active" />바나나 -- 기본은 원래 false !


전체코드

<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>속성 설정</h1>
<input type="text" name="mock" th:name="userName"/> <!--/*== <input type="text" name="userName" > */-->

<h1>속성 추가</h1>
<input type="text" class="text" th:attrappend="class= ' large'" />
<br>
<input type="text" class="text" th:attrprepend="class= 'large '" />
<br>
<input type="text" class="text" th:classappend="large" />

<h1>checked 처리</h1>
<input type="checkbox" name="active" th:checked="true" />사과
<input type="checkbox" name="active" th:checked="false" />딸기
<input type="checkbox" name="active" />바나나
</body>
</html>

index.html

<p><a href="ifcondition">ifcondition.html</a></p>


ThymeleafController.java

	@GetMapping(value="ifcondition")
	public String ifcondition(Model model) {
		model.addAttribute("age", 15);
		model.addAttribute("movie", "베놈");
		model.addAttribute("today", "화요일");
		return "basic/ifcondition";
	}

ifcondition.html

<h3 th:text="'시청 불가'" th:if="${age < 19}"></h3>

 

 

<h3 th:text="'시청 불가'" th:if="${age lt 19}"></h3>

 

 

리액트

조건 ||

 

타임리프

조건 ?: - 조건이 거짓일 때 수행한다.

<h3 th:text="'시청 가능'" th:unless="${age > 19}"></h3>


<ul th:if="${movie == '베놈'}"> <!-- 조건이 맞으면 ul 태그가 실행되고, 거짓이면 수행되지 않는다. -->

<ul th:if="${movie == '베놈'}"><!-- 조건이 맞으면 ul 태그가 실행되고, 거짓이면 수행되지 않는다. -->
	<li>라스트 댄스</li>
	<li>기자 - 에디 브록</li>
	<li>심비오트</li>
</ul>


<th:block th:if="${today == '수요일'}">
	<h2>수요일에는 빨간 장미를 산다.</h2>
	<h2>수요일은 평일 중 가운데에 있다.</h2>
</th:block>


전체코드

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>if, unless</h1>
<hr>
<h3 th:text="'시청 불가'" th:if="${age < 19}"></h3>
<h3 th:text="'시청 불가'" th:if="${age lt 19}"></h3>
<h3 th:text="'시청 가능'" th:unless="${age > 19}"></h3>
<hr>
<ul th:if="${movie == '베놈'}"> <!-- 조건이 맞으면 ul 태그가 실행되고, 거짓이면 수행되지 않는다. -->
	<li>라스트 댄스</li>
	<li>기자 - 에디 브록</li>
	<li>심비오트</li>
</ul>
<hr>
<th:block th:if="${today == '수요일'}">
	<h2>수요일에는 빨간 장미를 산다.</h2>
	<h2>수요일은 평일 중 가운데에 있다.</h2>
</th:block>
</body>
</html>

 


index.html

<p><a href="condition">condition.html</a></p>


ThymeleafController.java

	@GetMapping(value="condition")
	public String condition(Model model) {
		PersonDTO aa = new PersonDTO("홍길동", 25);
		PersonDTO bb = new PersonDTO("김태리", 32);
		PersonDTO cc = new PersonDTO("이제훈", 40);
		
		List<PersonDTO> list = new ArrayList<>();
		list.add(aa);
		list.add(bb);
		list.add(cc);
		
		model.addAttribute("list", list);
		return "basic/condition";
	}

for(dto : PersonDTO)

<c:forEach var="dto" items="${list}" ?

</c:forEah>

 

<tr th:each="dto : ${list}"

위에 코드들과 같은 의미

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
table {
	padding: 5px;
	border-collapse: collapse;
}

td {
	text-align: center;
}
</style>
</head>
<body>
<h1>if, unless</h1>
<table border="1">
	<tr>
		<th width="50">개수</th>
		<th width="100">이름</th>
		<th width="70">나이</th>
	</tr>
	<tr th:each="dto : ${list}">
		<td>1</td>	
		<td th:text="${dto.name}">name</td>	
		<td th:text="${dto.age}">age</td>	
	</tr>
</table>
</body>
</html>

 


${dtoStat.index}

	<tr th:each="dto, dtoStat : ${list}">
		<td th:text="${dtoStat.index}">1</td>	
		<td th:text="${dto.name}">name</td>	
		<td th:text="${dto.age}">age</td>	
	</tr>

 

${dtoStat.count}

	<tr th:each="dto, dtoStat : ${list}">
		<td th:text="${dtoStat.count}">1</td>	
		<td th:text="${dto.name}">name</td>	
		<td th:text="${dto.age}">age</td>	
	</tr>

 


성인 청소년 구분해서 찍게하기

	@GetMapping(value="condition")
	public String condition(Model model) {
		PersonDTO aa = new PersonDTO("홍길동", 25);
		PersonDTO bb = new PersonDTO("김태리", 17);
		PersonDTO cc = new PersonDTO("이제훈", 40);
		
		List<PersonDTO> list = new ArrayList<>();
		list.add(aa);
		list.add(bb);
		list.add(cc);
		
		model.addAttribute("list", list);
		return "basic/condition";
	}

 

 

condition.html

	<tr th:each="dto, dtoStat : ${list}">
		<td th:text="${dtoStat.count}">1</td>	
		<td th:text="${dto.name}">name</td>	
		<td>
			<span th:text="${dto.age}">0</span>
			<span th:text="'성인'" th:if="${dto.age > 19}"></span>
			<span th:text="'청소년'" th:unless="${dto.age > 19}"></span>
		</td>	
	</tr>


switch

<h1>switch</h1>
<table border="1">
	<tr>
		<th width="50">번호</th>
		<th width="100">이름</th>
		<th width="100">나이</th>
	</tr>
	<tr th:each="dto, dtoStat : ${list}">
		<td th:text="${dtoStat.count}">1</td>	
		<td th:text="${dto.name}">name</td>	
		<td th:switch="${dto.age}">
			<span th:case="25">20대</span>
			<span th:case="17">10대</span>
			<span th:case="*">30대 이상</span>
		</td>	
	</tr>
</table>


전체코드

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
table {
	padding: 5px;
	border-collapse: collapse;
}

td {
	text-align: center;
}
</style>
</head>
<body>
<h1>if, unless</h1>
<table border="1">
	<tr>
		<th width="50">번호</th>
		<th width="100">이름</th>
		<th width="100">나이</th>
	</tr>
	<tr th:each="dto, dtoStat : ${list}">
		<td th:text="${dtoStat.count}">1</td>	
		<td th:text="${dto.name}">name</td>	
		<td>
			<span th:text="${dto.age}">0</span>
			<span th:text="'성인'" th:if="${dto.age > 19}"></span>
			<span th:text="'청소년'" th:unless="${dto.age > 19}"></span>
		</td>	
	</tr>
</table>

<h1>switch</h1>
<table border="1">
	<tr>
		<th width="50">번호</th>
		<th width="100">이름</th>
		<th width="100">나이</th>
	</tr>
	<tr th:each="dto, dtoStat : ${list}">
		<td th:text="${dtoStat.count}">1</td>	
		<td th:text="${dto.name}">name</td>	
		<td th:switch="${dto.age}">
			<span th:case="25">20대</span>
			<span th:case="17">10대</span>
			<span th:case="*">30대 이상</span>
		</td>	
	</tr>
</table>
</body>
</html>

index.html

<p><a href="each">each.html</a></ p >


ThymeleafController.java

	@GetMapping(value="each")
	public String each(Model model) {
		PersonDTO aa = new PersonDTO("홍길동", 25);
		PersonDTO bb = new PersonDTO("김태리", 17);
		PersonDTO cc = new PersonDTO("이제훈", 40);
		
		List<PersonDTO> list = new ArrayList<>();
		list.add(aa);
		list.add(bb);
		list.add(cc);
		
		model.addAttribute("list", list);
		return "basic/each";
	}

each.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
table {
	padding: 5px;
	border-collapse: collapse;
}

td {
	text-align: center;
}
</style>
</head>
<body>
<h1>기본 테이블</h1>
<table border="1">
	<tr>
		<th width="100">이름</th>
		<th width="100">나이</th>
	</tr>
	<tr th:each="dto : ${list}">
		<td th:text="${dto.name}">name</td>	
		<td th:text="${dto.age}">0</td>	
	</tr>
</table>

<h1>반복 상태 유지</h1>
<table border="1">
	<tr>
		<th width="50">번호</th>
		<th width="100">이름</th>
		<th width="100">나이</th>
		<th width="500">기타</th>
	</tr>	
	
	<tr th:each="dto, dtoStat : ${list}">
		<td th:text="${dtoStat.count}">1</td>
		<td th:text="${dto.name}">name</td>
		<td th:text="${dto.age}">age</td>
		<td>
			index = <span th:text="${dtoStat.index}"></span><br>
			count = <span th:text="${dtoStat.count}"></span><br>
			size = <span th:text="${dtoStat.size}"></span><br>
			even? = <span th:text="${dtoStat.even}"></span><br>
			odd? = <span th:text="${dtoStat.odd}"></span><br>
			first? = <span th:text="${dtoStat.first}"></span><br>
			last? = <span th:text="${dtoStat.last}"></span><br>
			current? = <span th:text="${dtoStat.current}"></span>
		</td>
	</tr>
</table>
</body>
</html>


index.html

<p><a href="block">block.html</a></p>


ThymeleafController.java

	@GetMapping(value="each")
	public String block(Model model) {
		PersonDTO aa = new PersonDTO("홍길동", 25);
		PersonDTO bb = new PersonDTO("김태리", 17);
		PersonDTO cc = new PersonDTO("이제훈", 40);
		
		List<PersonDTO> list = new ArrayList<>();
		list.add(aa);
		list.add(bb);
		list.add(cc);
		
		model.addAttribute("list", list);
		return "basic/block";
	}

block.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
span {
	color: blue;
}
</style>
</head>
<body>
	<th:block th:each="dto : ${list}">
		<div>
			이름 : <span th:text="${dto.name}"></span>&emsp;
			나이 : <span th:text="${dto.age}"></span>&emsp;
		</div>
		<div>
			요약 : <span th:text="${dto.name} + ' / ' + ${dto.age}"></span> 
		</div>
		<br>
	</th:block>
</body>
</html>

c


index.html

<p><a href="link">link.html</a></p>


ThymeleafController.java

	@GetMapping(value="link")
	public String link() {
		return "basic/link";
	}
	
	@GetMapping(value="hello")
	@ResponseBody
	public String hello() {
		return "Basic URL";
	}

link.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>URL 링크</h1>
<ul>
	<li><a th:href="@{/hello}">Basic URL</a></li>
</ul>
</body>
</html>

 

 


<li><a th:href="@{/hello(name=${'hong'}, age=${25})}">Query Param</a></li>

<!--/* http://localhost:8080/hello?name=hong&age=25 */-->

 

 

	@GetMapping(value="hello")
	@ResponseBody
	public String hello(@RequestParam(name="name") String name, 
						@RequestParam(name="age") int age) {
		return name + " / " + age;
	}


<li><a th:href="@{/hello(name=${name}, age=${age})}">Query Param</a></li>

	@GetMapping(value="hello")
	@ResponseBody
	public String hello(@RequestParam(name="name", defaultValue="noname") String name, 
						@RequestParam(name="age", defaultValue="0") int age) {
		return name + " / " + age;
	}


 <li><a th:href="@{/hello/{name}/{age}(name=${'hong'}, age=${25})}">Path Variable</a></li>

<!--/* http://localhost:8080/hello/hong/25 */-->

 

주소가 저렇게 들어가는 것이기 때문에

@RequestParam으로 받는게 아니라 @PathVariable으로 받아야한다 !!

	@GetMapping(value="hello2/{name}/{age}")
	@ResponseBody
	public String hello2(@PathVariable("name") String name, 
						 @PathVariable("age") int age) {
		return name + " / " + age;
	}


<li><a th:href="@{/hello3/{name}(name=${'hong'}, age=${25})}">Path Variable + Query Param</a></li>

	@GetMapping(value="/hello3/{name}")
	@ResponseBody
	public String hello3(@PathVariable("name") String name,
						@RequestParam("age") int age) {
		return name + " / " + age;
	}


<ul>
	<li><a th:href="@{/select}">select 요청</a></li>
	<li><a th:href="@{/insert(pageno=${pageno})}">Query 문자열로 pageno=1000을 지정하여 /insert 요청</a></li>
</ul>
	@GetMapping(value="/select")
	@ResponseBody
	public String select() {
		return "select 요청";
	}
	
	@GetMapping(value="/insert")
	@ResponseBody
	public String insert(@RequestParam(name="pageno", defaultValue="1000") int pageno) {

		return "pageno = " + pageno;
	}


<ul>
	<li><a th:href="@{/select}">select 요청</a></li>
	<li><a th:href="@{/insert(pageno=${pageno})}">Query 문자열로 pageno=1000을 지정하여 /insert 요청</a></li>
	<li>
		<a th:href="@{/character/detail/{name}/{number}(name=${'hong'}, number=${25})}">
			line 캐릭터 중 다선 번째 정보로 요청
		</a>
	</li>
</ul>
	@GetMapping(value="character/detail/{name}/{number}")
	@ResponseBody
	public String character_detail(@PathVariable("name") String name, 
								   @PathVariable("number") int number) {

		return name + " / " + number;
	}

전체코드

link.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>URL 링크</h1>
<ul>
	<li><a th:href="@{/hello}">Basic URL</a></li>
	
	<li><a th:href="@{/hello(name=${'hong'}, age=${25})}">Query Param</a></li>
	<li><a th:href="@{/hello(name=${name}, age=${age})}">Query Param</a></li>
	<!--/* http://localhost:8080/hello?name=hong&age=25 */-->
	
	<li><a th:href="@{/hello2/{name}/{age}(name=${'hong'}, age=${25})}">Path Variable</a></li>
	<!--/* http://localhost:8080/hello/hong/25 */-->
	
	<li><a th:href="@{/hello3/{name}(name=${'hong'}, age=${25})}">Path Variable + Query Param</a></li>
</ul>
<hr>
<ul>
	<li><a th:href="@{/select}">select 요청</a></li>
	<li><a th:href="@{/insert(pageno=${pageno})}">Query 문자열로 pageno=1000을 지정하여 /insert 요청</a></li>
	<li>
		<a th:href="@{/character/detail/{name}/{number}(name=${'hong'}, number=${25})}">
			line 캐릭터 중 다선 번째 정보로 요청
		</a>
	</li>
</ul>
</body>
</html>

 

 

ThymeleafController.java

	@GetMapping(value="hello")
	@ResponseBody
	public String hello(@RequestParam(name="name", defaultValue="noname") String name, 
						@RequestParam(name="age", defaultValue="0") int age) {
		return name + " / " + age;
	}
	
	@GetMapping(value="hello2/{name}/{age}")
	@ResponseBody
	public String hello2(@PathVariable("name") String name, 
						 @PathVariable("age") int age) {
		return name + " / " + age;
	}
	
	@GetMapping(value="/hello3/{name}")
	@ResponseBody
	public String hello3(@PathVariable("name") String name,
						@RequestParam("age") int age) {
		return name + " / " + age;
	}
	
	@GetMapping(value="/select")
	@ResponseBody
	public String select() {
		return "select 요청";
	}
	
	@GetMapping(value="/insert")
	@ResponseBody
	public String insert(@RequestParam(name="pageno", defaultValue="1000") int pageno) {

		return "pageno = " + pageno;
	}

index.html

<p><a href="basic">basic.html</a></p>


	@GetMapping(value="basicobjects")
	public String basicobjects() {
		return "basic/basicobjects";
	}

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>표현식 기본 객체 (Expression Basic Objects)</h1>
<ul>
	<li>locale = <span th:text="${#locale}">현재 요청의 언어 및 지역정보를 가져온다.</span></li>
</ul>
</body>
</html>


<h1>편의 객체</h1>
<ul>
	<li>Request Parameter = <span th:text="${param.paramData}"></span></li>
</ul>

 

index.html

	<p><a href="basicobjects">basicobjects.html(파라매터 X)</a></p>	
	<p><a href="basicobjects?paramData=Good">basicobjects.html(파라매터 O)</a></p>


${@ } 기호는 스프링 빈을 참조한다.

helloTest는 스프링 애플리케이션 컨텍스트에 등록한 빈의 이름이다.

helloTest 빈의 hello 메서드를 호출하고 결과를 템플릿에 출력한다.

 

<li>spring bean = <spant th:text="${@helloTest.hello('Spring Boot!!')}"></span></li>

<h1>편의 객체</h1>
<ul>
	<li>Request Parameter = <span th:text="${param.paramData}"></span></li>
	<li>spring bean = <spant th:text="${@helloTest.hello('Spring Boot!!')}"></span></li>
	<!-- /* -->
		${@ } 기호는 스프링 빈을 참조한다. 
		helloTest는 스프링 애플리케이션 컨텍스트에 등록한 빈의 이름이다.
		@Compnent, @Service, @Repository, ... 등 어노테이션을 사용하여 빈으로 생성된다.
		helloTest 빈의 hello 메서드를 호출하고 결과를 템플릿에 출력한다.
	<!--*/-->
</ul>

 

 

HelloTest.java

package thymeleaf.dto;

import org.springframework.stereotype.Component;

@Component("helloTest")
public class HelloTest {
	
	public String hello(String name) {
		return "안녕하세요 " + name;
	}
}


타임리프에서 [[]]는 표현식(Expression)을 나타내는 구문이다.

[[ ]] 안에 작성된 내용은 변수나 표현식을 평가하여 결과를 HTML에 삽입하는 데 사용된다.

 

[[${startTime}]]<br>

 

	@GetMapping(value="basicobjects")
	public String basicobjects(Model model) {
		LocalDateTime startTime = LocalDateTime.now();
		
		model.addAttribute("startTime", startTime);
		return "basic/basicobjects";
	}
<h2>날짜 및 시간 표현</h2>
<p>시작 시간: [[${startTime}]]</p>
<p>포맷 1: [[${#temporals.format(startTime, 'yyyy-MM-dd HH:mm:ss')}]]</p>
<p>포맷 2: [[${#temporals.format(startTime, 'yyyy년 MM월 dd일 HH시 mm분')}]]</p>

<!-- 
타임리프에서 [[]]는 표현식(Expression)을 나타내는 구문이다.

[[ ]] 안에 작성된 내용은 변수나 표현식을 평가하여 결과를 HTML에 삽입하는 데 사용된다.
 -->
<hr>

<h2>날짜/시간 함수 예시</h2>
<p>현재 날짜 객체: [[${#dates}]]</p>
<p>현재 시각 생성: [[${#dates.createNow()}]]</p>
<p>오늘 날짜 생성: [[${#dates.createToday()}]]</p>
<p>포맷 예시 (YYYY/MM/dd HH:mm): [[${#dates.format(#dates.createNow(), 'yyyy/MM/dd HH:mm')}]]</p>
<p>포맷 예시 (yyyy년 MM월 d일): [[${#dates.format(#dates.createNow(), 'yyyy년 MM월 d일')}]]</p>
<p>포맷 예시 (hh:mm:ss): [[${#dates.format(#dates.createNow(), 'hh:mm:ss')}]]</p>
<p>요일 이름: [[${#calendars.dayOfWeekName(#dates.createNow())}]]</p>


	@GetMapping(value="basicobjects")
	public String basicobjects(Model model) {
		LocalDateTime startTime = LocalDateTime.now();
		
		model.addAttribute("startTime", startTime);
		model.addAttribute("str", "  Spring Boot  ");
		return "basic/basicobjects";
	}

 

<!-- 타임리프에서 [[ ]]는 특정 문자열이나 변수의 값을 출력할 때 사용되는 표현식 -->
<p>문자열 유틸리티 기능:</p>
<ul>
    <li>Thymeleaf Strings 객체: [[${#strings}]]</li>
    <li>파라미터 name이 비어 있는지 확인: [[${#strings.isEmpty(param.name)}]]</li>
    <li>파라미터 startTime이 비어 있는지 확인: [[${#strings.isEmpty(param.startTime)}]]</li>
    <li>문자열 str이 비어 있는지 확인: [[${#strings.isEmpty(str)}]]</li>
    <li>문자열 str의 길이: [[${#strings.length(str)}]]</li>
    <li>문자열 str을 소문자로 변환: [[${#strings.toLowerCase(str)}]]</li>
    <li>문자열 str 출력: [[${str}]]</li>
    <li>문자열 str의 앞뒤 공백 제거: [[${#strings.trim(str)}]]</li>
</ul>


	@GetMapping(value="basicobjects")
	public String basicobjects(Model model) {
		LocalDateTime startTime = LocalDateTime.now();
		
		model.addAttribute("startTime", startTime);
		model.addAttribute("str", "  Spring Boot  ");
		model.addAttribute("num", "123456789.389");
		return "basic/basicobjects";
	}

 

 

<ul>
    <!-- 기본 숫자 출력 -->
    <li>${num} = <span th:text="${num}"></span></li>

    <!-- 천 단위 콤마 형식으로 정수 출력 -->
    <li>
        ${#numbers.formatInteger(num, 3, 'COMMA')} = 
        <span th:text="${#numbers.formatInteger(num, 3, 'COMMA')}"></span>
    </li>

    <!-- 통화 형식으로 출력 -->
    <li>
        ${#numbers.formatCurrency(num)} = 
        <span th:text="${#numbers.formatCurrency(num)}"></span>
    </li>

    <!-- 소수점 포함, 천 단위 콤마 및 소수점 두 자리 형식으로 출력 -->
    <li>
        ${#numbers.formatDecimal(num, 3, 'COMMA', 2, 'POINT')} = 
        <span th:text="${#numbers.formatDecimal(num, 3, 'COMMA', 2, 'POINT')}"></span>
    </li>
</ul>


[[${param}]]<br>
[[${param.size()}]]<br>
[[${param.isEmpty()}]]<br>
[[${param.containsKey('foo')}]]<br>


	@GetMapping(value="basicobjects")
	public String basicobjects(HttpSession session, Model model) {
		LocalDateTime startTime = LocalDateTime.now();
		
		//세션
		session.setAttribute("memId", "hong");
		session.setAttribute("memName", "홍길동");
		
		model.addAttribute("startTime", startTime);
		model.addAttribute("str", "  Spring Boot  ");
		model.addAttribute("num", "123456789.389");
		return "basic/basicobjects";
	}
[[${session}]]<br>
[[${session.memId}]]<br>
[[${session.size()}]]<br>
[[${session.isEmpty()}]]<br>
[[${session.keySet()}]]<br>


src/main/resources

    templates

          index.html

          basic(폴더)

               fragmentMain1.html

               fragmentMain2.html

                fragment(폴더)

                       menu.html

                       info.html

                       footer.html

 

menu.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div th:fragment="header">
	<a href="https://spring.io/">스프링페이지</a>
	<a href="https://www.thymeleaf.org/">타임리프페이지</a>
</div>
</body>
</html>

info.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div th:fragment="info">
	문의 사항은 admin@java.com 메일로 보내세요
</div>
</body>
</html>

footer.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<footer th:fragment="foot(styles)" th:attr="style=${styles}">푸터 자리</footer>
<footer th:fragment="footParam(param1, param2, styles)" th:attr="style=${styles}">
	<p>foot 파라미터 자리 입니다.</p>
    <p th:text="${param1}"></p>
    <p th:text="${param2}"></p>
</footer>
</body>
</html>

fragmentMain1.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
header {
	height : 100px;
	background-color : yellow;
}
footer {
	height : 100px;
	background-color : pink;
}
section {
	height : 200px;
	background-color : green;
}
</style>
</head>
<body>
	<header th:insert="basic/fragment/menu :: header">여기는 menu</header>
	<section>
            여기는 fragmentMain1.html 페이지 입니다.
	</section>
	<footer th:insert="basic/fragment/info :: info">여기는 info</footer>
</body>
</html>

<!--/*--> 
th:insert는 다른 HTML 파일의 특정 프래그먼트를 현재 문서에 삽입

"basic/fragment/menu :: header"는 basic/fragment/menu.html 파일의 header라는 이름의 프래그먼트를 삽입하겠다는 의미
<!--*/-->


fragmentMain2.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>부분 포함 테스트</h1>
<hr>
<h2>부분 포함 insert</h2>
<div th:insert="~{basic/fragment/footer :: foot('color: red;')}"></div>

<h2>부분 포함 replace</h2>
<div th:replace="~{basic/fragment/footer :: foot('color: blue;')}"></div>

<h2>부분 포함 단순 표현식</h2>
<div th:insert="basic/fragment/footer :: foot('color: magenta;')"></div>

<h1>파라미터 사용</h1>
<div th:replace="~{basic/fragment/footer :: footParam('데이터1', '데이터2', 'color: green;')}"></div>
<div th:replace="basic/fragment/footer :: footParam('데이터1', '데이터2', 'color: green;')"></div>

</body>
</html>

<!--/* ~{}는 타임리프에서 리소스의 상대 경로를 지정할 때 사용되는 구문이다. */-->