如何檢查 Thymeleaf 是否定義了變數
一、簡介
在本教程中,我們將學習如何使用三種不同的方法檢查 Thymeleaf 中是否定義了變數。為此,我們將使用 Spring MVC 和 Thymeleaf 建立一個簡單的 Web 應用程序,該應用程式具有單一視圖,如果設定了給定變量,該視圖將顯示伺服器日期和時間。
2. 設定
在深入研究這些方法之前,我們需要進行一些初始設定。讓我們從Thymeleaf 依賴項開始:
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
現在,讓我們建立checkVariableIsDefined視圖:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
th:with="lang=${#locale.language}" th:lang="${lang}">
<head>
<title>How to Check if a Variable is Defined in Thymeleaf</title>
</head>
<body>
<!-- we'll add here the relevant code for each method -->
</body>
</html>
我們也為此視圖定義兩個新端點:
@RequestMapping(value = "/variable-defined", method = RequestMethod.GET)
public String getDefinedVariables(Model model) {
DateFormat dateFormat =
DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.getDefault());
model.addAttribute("serverTime", dateFormat.format(new Date()));
return "checkVariableIsDefined.html";
}
@RequestMapping(value = "/variable-not-defined", method = RequestMethod.GET)
public String getNotDefinedVariables(Model model) {
return "checkVariableIsDefined.html";
}
第一個端點載入已定義serverTime變數的checkVariableIsDefined視圖,而後一個端點載入未定義變數的相同視圖。
此設定將幫助我們測試以下部分中介紹的方法。
3. 使用#ctx對象
我們將探索的第一個方法使用 context 對象,其中包含 Thymeleaf 模板引擎處理模板所需的所有變量,包括對用於外部化訊息的Locale的引用。上下文是獨立應用程式的IContext介面或 Web 應用程式的[IWebContext](https://www.thymeleaf.org/apidocs/thymeleaf/3.1.2.RELEASE/org/thymeleaf/context/IWebContext.html)介面的實作。
我們可以使用#ctx表示法來存取 Thymeleaf 模板中的上下文物件。讓我們將相關程式碼加入checkVariableIsDefined視圖:
<div th:if="${#ctx.containsVariable('serverTime')}" th:text="'Server Time Using the #ctx Object Is: ' + ${serverTime}"/>
現在,讓我們寫兩個整合測試來驗證這個方法:
private static final String CTX_OBJECT_MSG = "Server Time Using the #ctx Object Is: ";
@Test
public void whenVariableIsDefined_thenCtxObjectContainsVariable() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/variables-defined"))
.andExpect(status().isOk())
.andExpect(view().name("checkVariableIsDefined.html"))
.andExpect(content().string(containsString(CTX_OBJECT_MSG)));
}
@Test
public void whenVariableNotDefined_thenCtxObjectDoesNotContainVariable() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/variables-not-defined"))
.andExpect(status().isOk())
.andExpect(view().name("checkVariableIsDefined.html"))
.andExpect(content().string(not(containsString(CTX_OBJECT_MSG))));
}
4. 使用if條件
以下方法使用if條件。讓我們更新checkVariableIsDefined視圖:
<div th:if="${serverTime}" th:text="'Server Time Using #th:if Conditional Is: ' + ${serverTime}"/>
如果變數為 null,則if條件評估為false 。
現在,讓我們來看看整合測試:
private static final String IF_CONDITIONAL_MSG = "Server Time Using #th:if Conditional Is: ";
@Test
public void whenVariableIsDefined_thenIfConditionalIsTrue() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/variable-defined"))
.andExpect(status().isOk())
.andExpect(view().name("checkVariableIsDefined.html"))
.andExpect(content().string(containsString(IF_CONDITIONAL_MSG)));
}
@Test
public void whenVariableIsNotDefined_thenIfConditionalIsFalse() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/variable-not-defined"))
.andExpect(status().isOk())
.andExpect(view().name("checkVariableIsDefined.html"))
.andExpect(content().string(not(containsString(IF_CONDITIONAL_MSG))));
}
若下列任一條件為true ,則if條件被評估為真:
- 該變數是一個布林值,值為
true - 該變數是一個非零數字
- 該變數是非零字符
- 這個變數是一個不同於
“false”、“off”、“no”的字串 - 該變數不是布林值、數字、字元或字串
請注意,如果設定了變量,但其值為“false” 、 “no”, “off”或0 ,則if條件評估為false ,如果我們的目的只是檢查,這可能會導致一些不良的副作用如果設定了變數。讓我們透過更新視圖來說明這一點:
<div th:if='${"false"}' th:text='"Evaluating \"false\"'/>
<div th:if='${"no"}' th:text='"Evaluating \"no\"'/>
<div th:if='${"off"}' th:text='"Evaluating \"off\"'/>
<div th:if="${0}" th:text='"Evaluating 0"'/>
接下來,讓我們建立整合測試:
@Test
public void whenVariableIsDefinedAndNotTrue_thenIfConditionalIsFalse() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/variable-defined"))
.andExpect(status().isOk())
.andExpect(view().name("checkVariableIsDefined.html"))
.andExpect(content().string(not(containsString("Evaluating \"false\""))))
.andExpect(content().string(not(containsString("Evaluating \"no\""))))
.andExpect(content().string(not(containsString("Evaluating \"off\""))))
.andExpect(content().string(not(containsString("Evaluating 0"))));
}
我們可以透過檢查變數不為空來解決這個問題:
<div th:if="${serverTime != null}" th:text="'Server Time Using #th:if Conditional Is: ' + ${serverTime}"/>
5.使用unless條件
最後一個方法使用unless它是if條件的倒數。讓我們相應地更新視圖:
<div th:unless="${serverTime == null}" th:text="'Server Time Using #th:unless Conditional Is: ' + ${serverTime}"/>
我們也測試一下這個方法是否會產生預期的結果:
private static final String UNLESS_CONDITIONAL_MSG = "Server Time Using #th:unless Conditional Is: ";
@Test
public void whenVariableIsDefined_thenUnlessConditionalIsTrue() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/variable-defined"))
.andExpect(status().isOk())
.andExpect(view().name("checkVariableIsDefined.html"))
.andExpect(content().string(containsString(IF_CONDITIONAL_MSG)));
}
@Test
public void whenVariableIsNotDefined_thenUnlessConditionalIsFalse() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/variable-not-defined"))
.andExpect(status().isOk())
.andExpect(view().name("checkVariableIsDefined.html"))
.andExpect(content().string(not(containsString(UNLESS_CONDITIONAL_MSG))));
}
六,結論
在本文中,我們學習了三種檢查 Thymeleaf 中是否定義變數的方法。第一個方法使用#ctx物件和containsVariable方法,而第二個和最後一個方法使用條件語句if及其相反的unless 。
像往常一樣,完整的程式碼可以在 GitHub 上找到。