[Spring] Thymeleaf (동적 콘텐츠 생성)

ma0·2024년 9월 11일

JSP

목록 보기
6/7

Thymeleaf

= 자바 기반 웹 프레임워크에서 매우 유용하게 쓰이는 템플릿 엔진

= HTML 파일을 그대로 유지하면서 동적인 데이터를 바인딩

  • HTML 친화적 : Thymeleaf 템플릿은 확장명이 .html, 서버에서 동적 데이터 주입할 때만 달라짐
  • 서버 사이드 렌더링 : 동적 웹 페이지 제공 가능
  • 특정 파일이나 요청을 보낼 때는 @, 변수를 꺼낼 때는 $ 사용

연산자


1. Text 출력

th:text
= 서버에서 저장된 텍스트 출력
→ 출력 데이터 내 tag 포함되어 있어도 text로 출력
→ null이나 빈문자는 표현 X, 숫자 또는 날짜도 텍스트로 출력
→ 객체의 경우 toString()이나 멤버변수의 getter() 값 출력

th:utext
= 서버에서 저장된 텍스트에 tag 포함 시, tag를 rendering 하여 출력

Controller

@Controller
public class ThymeleafController {
	@GetMapping("/display/text")
	public String text(Model model) {
		// 문자 출력을 위한 데이터 준비
		String korean = "대한민국 ~~ *♥";
		String english = "Hello, everyone!!!";
		String tag = "<marquee>돌이 굴러가유~</marquee>";
		
		// 숫자 출력을 위한 데이터 준비
		int age = 30;
		double pi = Math.PI;
		
		// URL 출력을 위한 데이터 준비
		String url="https://naver.com";
		
		// 빈 데이터와 NULL 데이터 준비
		String nullData = null;
		String emptyData = "";
		
		model.addAttribute("korean", korean);
		model.addAttribute("english", english);
		model.addAttribute("tag", tag);
		
		model.addAttribute("age", age);
		model.addAttribute("pi", pi);
		model.addAttribute("url", url);
		
		model.addAttribute("nullData", nullData);
		model.addAttribute("emptyData", emptyData);
		
		return "thyme_text";
	}

thyme_text.html

<h2>Thymeleaf text 출력</h2>
  <div>
      <a th:href="@{/}">홈으로</a>
  </div>

  <h3>1. 문자 출력</h3>
  <p>한글 출력: <span th:text="${korean}">한글</span></p>
  <p>영문 출력: <span th:text="${english}">영문</span></p>
  <p>태그 출력: <span th:text="${tag}">태그</span></p>
  <p>정수 출력: <span th:text="${age}">정수</span></p>
  <p>실수 출력: <span th:text="${pi}">실수</span></p>
  <p>URL 출력: <span th:text="${url}">실수</span></p>
  <br>
  
  <p>태그 출력: <span th:utext="${tag}">태그</span></p>
  <p>URL 출력: <a th:href="${url}" th:text="${url}">네이버</a></p>
 
  
  <hr>
  <h3>2. 태그의 Inner 위치에서 Thymeleaf 문법을 사용하면...</h3>
  <p>한글 출력: [[${korean}]] </p>
  <p>영문 출력: [[${english}]] </p>
  
  <hr>
  <h3>3. 빈 데이터 출력(아무것도 출력되지 않음)</h3>
  <p>null 출력: <span th:text="${nullData}">null</span></p>
  <p>빈 문자 출력: <span th:text="${emptyData}">빈 문자</span></p>
  • <marquee> 태그가 붙은 tag는 th:utext 사용할 경우 작동
  • tag의 inner 에서는 [[ ${} ]]

결과 화면


2. 조건문과 반복문

1. 객체 출력

th:objext : 서버에서 저장된 객체값 출력

Cotroller

@GetMapping("/display/condition")
	public String condition(Model model) {
		// 일반 객체
		Friend friend = new Friend("홍길동", 25, "010-1234-1111", LocalDate.of(2003, 12, 5), true);

thyme_condition.html

<p th:text="${friend}">객체</p>

model.addAttribute("friend", friend);

2. 각각의 데이터 출력

Controller - 위와 동일

DTO - Friend.java

@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
@ToString
public class Friend {
	private String username;
	private Integer age;
	private String phone;
	private LocalDate birthday;
	private Boolean active;
}

HTML

 <h3>2. 각각의 데이터로 출력</h3>
 <p th:text="${friend.username}">이름</p>
 <p th:text="${friend.age} + 10">나이</p>
 <p th:text="${friend.phone}">전화번호</p>
 <p th:text="${friend.birthday}">생년월일</p>
 <p th:text="${friend.active} ? '외향적' : '내향적'">성향</p> 

3. Object 단위 데이터 출력

HTML

 <h2>3. Object 단위 데이터로 출력</h2>
   <div th:object="${friend}">
	    <p th:text="*{username}">이름</p>
	    <p th:text="*{age} + 10">나이</p>
	    <p th:text="*{phone}">전화번호</p>
	    <p th:text="*{birthday}">생년월일</p>
	    <p th:text="*{active} ? '외향적' : '내향적'">성향</p>
   </div>

4. List 데이터 출력

Controller

// Iterable 데이터
List<String> list = Arrays.asList("사과", "배", "딸기", "복숭아", "포도", "오렌지");
  
model.addAttribute("list", list);

HTML

<h2>4. List에 들어있는 데이터 출력</h2>
    <p>개수: [[${list.size()}]]</p>
    <div th:each="item : ${list}">
    	<span th:text="${item}"></span>&nbsp;
    </div>

5. Map에 들어 있는 데이터 출력

Controller

 // Map 데이터
Map<Integer, Friend> map = new HashMap<>();
map.put(10, new Friend("손오공", 25, "010", LocalDate.of(2000, 12, 25), true));
map.put(20, new Friend("저팔계", 30, "011", LocalDate.of(1994, 10, 1), false));
map.put(30, new Friend("사오정", 21, "019", LocalDate.of(2003, 1, 5), true));
		
model.addAttribute("map", map);

HTML

<h2>5. Map에 들어있는 데이터 출력</h2>
   <p>개수: [[${map.size()}]]</p>
   <p>10번 데이터: [[${map[10]}]]</p>
   
   <h3>Map 정보 전체 순회</h3>
   <ul th:each="f : ${map}">
   	<li>번호: [[${f.key}]]</li>
   	<li>이름: [[${f.value.username}]]</li>
   	<li>나이: [[${f.value.age}]]</li>
   	<li>전화번호: [[${f.value.phone}]]</li>
   	<li>성향: [[${f.value.active} ? '외향적' : '내성적']]</li>
   </ul>
  • 전체 순회의 경우, 모든 3개의 데이터가 표시

5. 숫자 정보 전체 순회

Controller

List<Integer> nList = new ArrayList<>();
for(int i=1; i<=20; ++i) 
	nList.add(i*3);

model.addAttribute("nList", nlist);

HTML

 <h3>6. 숫자 정보 전체 순회</h3>
    <div th:each="n, status : ${nList}">
    	<span th:if="${status.count % 3 == 0}" style="color:red;">[[${status.count}]] : *****</span>
    	<span th:unless="${status.count % 3 == 0}">----------</span>
    </div>
  • *의 개수가 3의 배수인 경우 빨간색으로 출력, 아닌 경우 ----- 출력



관련 Attribute : th:href, th:src, th:action 등 외부 URL 사용 태그

  • @{...}과 함께 사용
  • <img>, <a>, <form> 태그의 attribute와 동일

예시 코드

1. 이미지 URL

<a href=".../index.html" th:href="@{/}">
  	<img th:src="@{/images/logo.png}" alt="첫화면">
</a>

2. 쿼리 String 전송

<a th:href="@{/display/sendOne(username=Gildong, age=23}">

= localhost:8080/display/sendOne?username=Gildong&age=23 과 동일

3. 요청 URL로 form data 전송

<form th:action="@{/display/sendVO}" method="POST">


4. 기본 객체 표현



5. 기본 객체 다루기 (숫자)

  • 정수 : #numbers.formatInteger
  • 실수 : #numbers.formatDecimal
  • 백분율 : #numbers.formatPercent(값, 0, n) =>소숫점 n자리 표현
  • 통화 기호: #numbers.formatCurrency()

html

<h2>기본 객체 다루기(숫자)</h2>
    <ul>
        <li>Integer(기본): <span th:text="${intNum}"></span></li>
        <li>Integer 10자리: <span th:text="${#numbers.formatInteger(intNum, 10)}"></span></li>
        <li>Integer POINT: <span th:text="${#numbers.formatInteger(intNum, 3, 'POINT')}"></span></li>
        <li>Integer COMMA: <span th:text="${#numbers.formatInteger(intNum, 3, 'COMMA')}"></span></li>
        <li>Integer NONE: <span th:text="${#numbers.formatInteger(intNum, 3, 'NONE')}"></span></li>
        <li>Integer 3자리: <span th:text="${#numbers.formatInteger(intNum, 3)}"></span></li>
        
        <li>----------------------</li>       
        <li>Double(기본): <span th:text="${doubleNum}"></span></li>
        <li>Double(소수 2자리): <span th:text="${#numbers.formatDecimal(doubleNum, 3, 2)}"></span></li>
        <li>Double(천단위 콤마, 소수 2자리): <span th:text="${#numbers.formatDecimal(doubleNum, 3, 'COMMA', 2, 'POINT')}"></span></li>
        <li>Double(천단위 공백, 소수 3자리): <span th:text="${#numbers.formatDecimal(doubleNum, 3, 'WHITESPACE', 3, 'POINT')}"></span></li>
        
        <li>----------------------</li>
        <li>Percent(기본): <span th:text="${percent}"></span></li>
        <li>Percent(백분율, 2자리): <span th:text="${#numbers.formatPercent(percent, 0, 2)}"></span></li>
        
        <li>----------------------</li>
        <li>Money: <span th:text="${money}"></span></li>
        <li>Money(통화기호): <span th:text="${#numbers.formatCurrency(money)}"></span></li>
    </ul>

결과 화면



6. Thymeleaf로 파라미터 보내기 (하이퍼링크 사용)

html

<li><a th:href="@{/display/receive(name=홍길동, age=35)}"></a></li>

Controller

@GetMapping("/display/receive")
public String receive(
  @RequestParam(name="name", defaultValue="모모") String name,
  @RequestParam(age="age", defaultValue="23") int age
  ){
  
  System.out.println(name+", "+age)
  
  return "index";
  

결과 - 콘솔창

profile
우당탕탕 개발 간잽 일기 - 간잽이 수백 번이면 전문가일지도?

0개의 댓글