if
, unless
(if의 반대)
package hello.thymeleaf.basic;
import lombok.Data;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Controller
@RequestMapping("/basic")
public class BasicController {
...
@GetMapping("/condition")
public String condition(Model model) {
addUsers(model);
return "basic/condition";
}
private void addUsers(Model model) {
List<User> list = new ArrayList<>();
list.add(new User("UserA", 10));
list.add(new User("UserA", 20));
list.add(new User("UserA", 30));
model.addAttribute("users", list);
}
...
}
<!DOCTYPE html>
<html xmlns:th="<http://www.thymeleaf.org>">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>if, unless</h1>
<table border="1">
<tr>
<th>count</th>
<th>username</th>
<th>age</th>
</tr>
<tr th:each="user, userStat : ${users}">
<td th:text="${userStat.count}">1</td>
<td th:text="${user.username}">username</td>
<td>
<span th:text="${user.age}">0</span>
<span th:text="'미성년자'" th:if="${user.age lt 20}"></span>
<span th:text="'미성년자'" th:unless="${user.age ge 20}"></span>
</td>
</tr>
</table>
<h1>switch</h1>
<table border="1">
<tr>
<th>count</th>
<th>username</th>
<th>age</th>
</tr>
<tr th:each="user, userStat : ${users}">
<td th:text="${userStat.count}">1</td>
<td th:text="${user.username}">username</td>
<td th:switch="${user.age}">
<span th:case="10">10살</span>
<span th:case="20">20살</span>
<span th:case="*">기타</span>
</td>
</tr>
</table>
</body>
</html>
if, unless
타임리프는 해당 조건이 맞지 않으면 태그 자체를 렌더링하지 않습니다.
만약 다음 조건이 false 인 경우 <span>...<span> 부분 자체가 렌더링 되지 않고 싹 사라집니다.
<!-- 이 부분이 그냥 사라집니다. -->
<span th:text="'미성년자'" th:if="${user.age lt 20}"></span>
unless 도 마찬가지로 조건이 맞지 않으면 싹 사라집니다.
switch
<aside> ❗ 타임리프에서 null check하기 - isEmpty
만약 view 단에서 보여줘야 하는 데이터가 없으면(아마도 DB에서 삭제된 경우) 프론트단에 데이터를 보여주는 div 태그를 없애야 합닌다.
그야 식은 죽 먹기죠. data가 null인지 아닌지 판단해서 null이 아닐 때만 보여주면 되는거 아니겠습니까? 아래 코드처럼요.
<div th:if = "${examData != null}"> ... <div>
그런데 문제가 하나 더 있네요. 만약 null 값이 아니라 빈 문자열이 들어온다면 어떻게 해야 하죠? 그럼 코드가 이런식이 되어야 할 것 같은데...
<div th:if = "${examData != ''}"> ... <div>
데이터가 null 일수도 있고 빈 문자열일 수도 있을 때도 있다면 조건문을 두 개 써야 겠군요…
그런데 그냥 컨트롤러에서 처리해서 넘겨준다면 조금 더 편할 것 같습니다.
if (examData.isEmpty()) {
model.addAttribute("examData", "nothing");
} else {
model.addAttribute("examData", examData);
}
그리고 뷰에서는
<div th:if="${examData != 'nothing'}"> ... </div>
이렇게 받으면 되는데 솔직히 좀 마음에 들지는 않네요.
오히려 자바 코드가 다섯줄이나 늘어나 버렸으니…
그렇지만! 사실 thymeleaf를 사용하고 있다면 아주 간단하게 해결할 수 있습니다.
<div th:if="${not #strings.isEmpty(examData)}"> ... </div>
isEmpty()를 사용하면 들어온 값이 null 이거나 빈 문자열일 때 true를 반환합니다.
참고로 체크를 하기 전에 trim() 메소드를 적용하기 때문에 빈 줄이나 공백도 같이 걸러진다는 것을 유의 해야합니다.
#strings utility 에는 String 객체를 위한 method드 들이 존재 합니다.
</aside>