如何访问Thymeleaf中包含点的Spring MVC模型属性名称

好吧,既然Spring Boot框架推荐了Thymeleaf模板引擎,那么我创建了一个使用http://start.spring.io选择 WebThymeleaf 依赖项的简单项目 .

由于以下 HomeControllerhome/about.html 模板工作正常 .

这是 HomeController 的java源代码:

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HomeController {
    @RequestMapping("/home/about")
    public String about(Model model) {
        model.addAttribute("title", "About");
        return "home/about";
    }
}

这是 home/about.html 的html源代码:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>Test for dot!</title>
</head>
<body>
<h1 th:text="${title}">H1Title</h1>
</body>
</html>

当我使用完整代码更改模型属性名称 with some dothome.about.title 如下:

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HomeController {
    @RequestMapping("/home/about")
    public String about(Model model) {
        model.addAttribute("home.about.title", "About");
        return "home/about";
    }
}

并且html代码变为:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>Test for dot!</title>
</head>
<body>
<h1 th:text="${home.about.title}">H1Title</h1>
</body>
</html>

好吧,发生了一些错误,这令人困惑!

那么,模型属性名称中 dot 的问题是什么?它是保留用法的特殊字符吗?以及如何使其工作?

我在StackOverflow中搜索并找到了类似的问题How to access a Spring MVC model attribute name that contain a dot in Freemarker?,但该问题的答案不适用于Thymeleaf .

回答(3)

2 years ago

点用于指代对象的属性/方法 . 当你有表达式 ${home.about.title} 时,它试图找到一个模型对象 home 并调用 home.getAbout().getTitle() . 通过做这样的事情,我已经能够解决这个问题

<!-- thymeleaf 2 -->
<span th:text="${#vars.get('home.about.title')}" />

<!-- thymeleaf 3 -->
<span th:text="${#vars.getVariable('home.about.title')}" />

但我不推荐它 . 你应该远离在模型属性中使用点字符 .

2 years ago

使用像这样的国际化消息并不是一个好习惯 .

对于Spring Boot项目,在 src/main/resources/ 中创建文件messages.properties(messages_cs.properties等)

并且 src/main/resources/messages.properties 的内容将是

home.about.title=About

然后在Thymeleaf你将使用hashtag而不是dollar .

<h1 th:text="#{home.about.title}">H1Title</h1>

2 years ago

如果这些不只是需要国际化的“消息”,或者您不能遵循标准约定,我认为最好的方法是创建一个包含所需属性的类 . 例如,Properties类是内置的(因为我相信JDK 7) .

在你的控制器中:

Properties props = new Properties();
props.setProperty("my.key", "my.value");
model.add(props, "Properties");

然后,在您的模板中:

<span th:text="${Properties.getProperty('my.key')}" />

当然,您可以创建自己的包装器类并更改方法名称以使访问更方便,因此最终结果可能更像:

<span th:text="${Store.get('my.key')}" />