从 Thymeleaf TEXT 模板调用静态方法 - 如何绕过受限模式
Calling a static method from Thymeleaf TEXT template - how to bypass the Restricted mode
是否可以从 Thymeleaf 文本模板调用静态方法?
Official guide 提到应该可以调用这样的方法:
<p th:text="${@myapp.translator.Translator@translateToFrench(textVar)}">Some text here...</p>
当我尝试在我的文本模板中使用它时(TemplateResolver 的模式设置为 TemplateMode.TEXT),我得到一个异常:
org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating OGNL expression: "@java.lang.System@currentTimeMillis()" (template: "template.txt" - line 1, col 18)
这是我的示例模板:
System millis: [(${@java.lang.System@currentTimeMillis()})]
google了一下,我也找到了这种调用方式:
System millis: [(${T(java.lang.System).currentTimeMillis()})]
失败并出现同样的错误。
我需要做的是以某种方式允许使用模板中的自定义数字格式化程序 class(#numbers
实用程序对象的功能对于我的情况来说还不够丰富)。
我可以通过将非静态 class 提供为上下文变量来调用方法,如下所示:
Some value: [(${formatter.format(someValue)})]
但我使用静态 class 会更容易,而无需将其显式添加到每个模板的上下文中。
顺便说一句,我不使用 Spring,只使用纯 Thymeleaf。
更新
我应该花更多时间来分析我得到的 Thymeleaf 异常的堆栈跟踪。
事实证明,此行为的根本原因是 org.thymeleaf.exceptions.TemplateProcessingException: Instantiation of new objects and access to static classes is forbidden in this context
异常,这是此更改的结果:https://github.com/thymeleaf/thymeleaf/issues/809
降级到 Thymeleaf 3.0.11“修复”了它。
现在我正在寻找一种解决方案,以在最新的 Thymeleaf(目前为 3.0.12)上绕过这种新的受限模式。我确信它对我来说是安全的,因为我是代码和模板的唯一作者。
https://github.com/thymeleaf/thymeleaf/issues/816#issuecomment-826401631 提供了关于为什么这样做以及可能的解决方法的大量信息。在你的情况下,最好在你的控制器中添加一个模型属性并使用它而不是在模板中调用静态方法。
@Controller
public class MyController {
public String myControllerMethod(Model model) {
model.addAttribute("time", System.currentTimeMillis());
return "name-of-the-thymeleaf-template";
}
}
并更新您的模板以使用:
System millis: [(${time})]
另一种方法是使用 th:with
属性。它有点冗长,但仍然应该给你同样的灵活性。 (这适用于 3.0.12.RELEASE
。)
[# th:with="time=${@java.lang.System@currentTimeMillis()}"]System millis: [[${time}]][/]
是否可以从 Thymeleaf 文本模板调用静态方法?
Official guide 提到应该可以调用这样的方法:
<p th:text="${@myapp.translator.Translator@translateToFrench(textVar)}">Some text here...</p>
当我尝试在我的文本模板中使用它时(TemplateResolver 的模式设置为 TemplateMode.TEXT),我得到一个异常:
org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating OGNL expression: "@java.lang.System@currentTimeMillis()" (template: "template.txt" - line 1, col 18)
这是我的示例模板:
System millis: [(${@java.lang.System@currentTimeMillis()})]
google了一下,我也找到了这种调用方式:
System millis: [(${T(java.lang.System).currentTimeMillis()})]
失败并出现同样的错误。
我需要做的是以某种方式允许使用模板中的自定义数字格式化程序 class(#numbers
实用程序对象的功能对于我的情况来说还不够丰富)。
我可以通过将非静态 class 提供为上下文变量来调用方法,如下所示:
Some value: [(${formatter.format(someValue)})]
但我使用静态 class 会更容易,而无需将其显式添加到每个模板的上下文中。
顺便说一句,我不使用 Spring,只使用纯 Thymeleaf。
更新
我应该花更多时间来分析我得到的 Thymeleaf 异常的堆栈跟踪。
事实证明,此行为的根本原因是 org.thymeleaf.exceptions.TemplateProcessingException: Instantiation of new objects and access to static classes is forbidden in this context
异常,这是此更改的结果:https://github.com/thymeleaf/thymeleaf/issues/809
降级到 Thymeleaf 3.0.11“修复”了它。
现在我正在寻找一种解决方案,以在最新的 Thymeleaf(目前为 3.0.12)上绕过这种新的受限模式。我确信它对我来说是安全的,因为我是代码和模板的唯一作者。
https://github.com/thymeleaf/thymeleaf/issues/816#issuecomment-826401631 提供了关于为什么这样做以及可能的解决方法的大量信息。在你的情况下,最好在你的控制器中添加一个模型属性并使用它而不是在模板中调用静态方法。
@Controller
public class MyController {
public String myControllerMethod(Model model) {
model.addAttribute("time", System.currentTimeMillis());
return "name-of-the-thymeleaf-template";
}
}
并更新您的模板以使用:
System millis: [(${time})]
另一种方法是使用 th:with
属性。它有点冗长,但仍然应该给你同样的灵活性。 (这适用于 3.0.12.RELEASE
。)
[# th:with="time=${@java.lang.System@currentTimeMillis()}"]System millis: [[${time}]][/]