在本教程中,我们将学习如何使用三种不同的方法检查Thymeleaf中是否定义了变量。为此,我们将使用Spring MVC 和 Thymeleaf构建一个简单的 Web 应用程序,该应用程序具有单个视图,如果设置了给定变量,该视图将显示服务器日期和时间。
设置
在深入研究这些方法之前,我们需要进行一些初始设置。让我们从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视图,而后一个端点加载未定义变量的相同视图。此设置将帮助我们测试以下部分中介绍的方法。
使用ctx对象
我们将探索的第一个方法使用 context 对象,它包含 Thymeleaf 模板引擎处理模板所需的所有变量,包括对用于外部化消息的Locale的引用。上下文是独立应用程序的IContext接口或 Web 应用程序的IWebContext接口的实现。
我们可以使用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)))); }
|
使用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)))); }
|
如果以下任一条件为真,则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}"/>
|
使用unless条件
最后一个方法使用except,它是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及其相反的except。