如何檢查 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 上找到。