以编程方式解析 Thymeleaf 模板

Posted

技术标签:

【中文标题】以编程方式解析 Thymeleaf 模板【英文标题】:Programmatically resolve Thymeleaf templates 【发布时间】:2016-04-16 09:35:11 【问题描述】:

我正在尝试使用 Thymeleaf 模板呈现 XML/JSON。我不想使用模板名称渲染视图,只想解析模板,如下所示。麻烦的是我得到的只是模板名称,而不是它的内容。

设置:

@Bean
SpringResourceTemplateResolver xmlTemplateResolver(ApplicationContext appCtx) 
    SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();

    templateResolver.setApplicationContext(appCtx);
    templateResolver.setPrefix("classpath:/templates/");
    templateResolver.setSuffix(".xml");
    templateResolver.setTemplateMode(XML);
    templateResolver.setCharacterEncoding(UTF_8.name());
    templateResolver.setCacheable(false);

    return templateResolver;


@Bean
SpringTemplateEngine templateEngine(ApplicationContext appCtx) 
    SpringTemplateEngine templateEngine = new SpringTemplateEngine();
    templateEngine.addTemplateResolver(xmlTemplateResolver(appCtx));

    return templateEngine;

模板(src/main/resources/templates/breakfast-menu.xml):

<?xml version="1.0" encoding="UTF-8"?>
<breakfast_menu>
    <food>
        <name>$item['name']</name>
        <price>$item['price']</price>
        <description>$item['description']</description>
        <calories>$item['calories']</calories>
    </food>
</breakfast_menu>

用法:

@Autowired
SpringTemplateEngine templateEngine;

someMethod() 
    Context context = new Context();
    context.setVariable("item", item);
    item.put("name", "Waffle");
    String content = templateEngine.process("breakfast-menu", context);

    // content == "breakfast-menu". WTH?

使用 Thymeleaf 3.0.0.BETA01。

【问题讨论】:

【参考方案1】:

我在 Thymeleaf user forum 的帮助下解决了这个问题。由于我不知道的原因,templateEngine.addTemplateResolver 不起作用,但 templateEngine.setTemplateResolver 起作用。 XML 和 JSON 输出的模板如下所示:

XML:

<?xml version="1.0" encoding="UTF-8"?>
<breakfast_menu>
    <food>
        <name th:text="$item['name']"></name>
        <price th:text="$item['price']"></price>
        <description th:text="$item['description']"></description>
        <calories th:text="$item['calories']"></calories>
    </food>
</breakfast_menu>

JSON:


  "food": 
    "name": "[[$item['name']]]",
    "price": "[[$item['price']]]",
    "description": "[[$item['description']]]",
    "calories": "[[$item['calories']]]"
   

【讨论】:

【参考方案2】:

为了完整起见,这里有一些代码来解析一个没有 Spring 的普通 Thymeleaf 模板。 这适用于 html,但您可以通过为 setTemplateMode 调用设置另一个参数来使其适应其他模板模式:

Maven 依赖:

<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf</artifactId>
    <version>3.0.12.RELEASE</version>
</dependency>

Java 类:

import java.util.Map;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.StringTemplateResolver;
public class ThymeleafResolver 
    public static String resolveHTMLWithThymeleaf(String html, Map<String, Object> variables) 
        TemplateEngine templateEngine = new TemplateEngine();
        StringTemplateResolver templateResolver = new StringTemplateResolver();
        templateResolver.setTemplateMode(TemplateMode.HTML);
        templateEngine.setTemplateResolver(templateResolver);
        Context context = new Context();
        context.setVariables(variables);
        return templateEngine.process(html, context);
    

测试用例 Java 代码:

Map<String, Object> variables = new HashMap<>();
variables.put("mytext", "Hello World");
String result = ThymeleafInterpreter.interpretHTMLWithThymeleaf("<html><body><span th:text=\"$mytext\"></span></body></html>", variables);
Assert.assertEquals("<html><body><span>Hello World</span></body></html>", result);

【讨论】:

Spring 依赖注入有几个好处,比如关注点分离、抽象和易于测试。我不认为将所有代码放在一个地方是一个好主意。如果您自己插入依赖项,我展示的代码可以在没有 Spring 上下文的情况下轻松使用。但是将它们分开可以使 IMO 代码更清晰。

以上是关于以编程方式解析 Thymeleaf 模板的主要内容,如果未能解决你的问题,请参考以下文章

Thymeleaf 模板 在spring boot 中的引用和应用

如何解析 Thymeleaf 模板以通过电子邮件发送?

thymeleaf模板。。。包含js。。。使用了if(a && b) 然后 && 不能通过模板引擎的解析。。。

Spring Boot使用Html

thymeleaf 模板引擎

Thymeleaf常用语法:模板注释