Spring Boot 中使用 Mustache 模板引擎指南

更新于 2025-12-30

Dhrubajyoti Bhattacharjee 2024-09-07

1. 概述

在本文中,我们将重点介绍如何在 Spring Boot 应用程序中使用 Mustache 模板来生成 HTML 内容。

Mustache 是一种**无逻辑(logic-less)**的模板引擎,因其简洁性而广受欢迎,适用于创建动态内容。


2. Maven 依赖

要在 Spring Boot 中使用 Mustache,我们需要在 pom.xml 中添加专用的 Spring Boot Starter:

<dependency>			
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mustache</artifactId>
</dependency>
<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-web</artifactId> 
</dependency>

此外,我们还需要 spring-boot-starter-web 依赖。


3. 创建模板

让我们通过一个示例,创建一个简单的 MVC 应用程序,使用 Spring Boot 在网页上展示文章列表。

首先编写文章内容的模板:

<div class="starter-template">
    {{#articles}}
    <h1>{{title}}</h1>
    <h3>{{publishDate}}</h3>
    <h3>{{author}}</h3>
    <p>{{body}}</p>
    {{/articles}}
</div>

我们将此 HTML 文件保存为 article.html,并在 index.html 中引用它:

<div class="container">
    {{>layout/article}}
</div>

这里,layout 是一个子目录,article 是模板文件的名称。

注意:默认情况下,Mustache 模板文件的扩展名为 .mustache。我们可以通过配置属性覆盖该默认值:

spring.mustache.suffix=.html

4. 控制器

现在我们编写用于展示文章的控制器:

@GetMapping("/article")
public ModelAndView displayArticle(Map<String, Object> model) {

    List<Article> articles = IntStream.range(0, 10)
      .mapToObj(i -> generateArticle("Article Title " + i))
      .collect(Collectors.toList());

    model.put("articles", articles);

    return new ModelAndView("index", model);
}

该控制器返回一个文章列表,供页面渲染。在文章模板中,以 {{#articles}} 开始、{{/articles}} 结束的标签会处理这个列表。

这将遍历传入的模型数据,并像 HTML 表格一样逐项渲染每个元素:

{{#articles}}...{{/articles}}

其中 generateArticle() 方法用于创建包含随机数据的 Article 实例。

注意:控制器返回的 Article 模型中的字段名必须与模板中的占位符名称一致。


测试应用

我们可以编写如下测试用例:

@Test
public void givenIndexPage_whenContainsArticle_thenTrue() {

    ResponseEntity<String> entity 
      = this.restTemplate.getForEntity("/article", String.class);
 
    assertEquals(entity.getStatusCode(), HttpStatus.OK);
    assertTrue(entity.getBody()
      .contains("Article Title 0"));
}

也可以通过以下命令启动应用进行手动测试:

mvn spring-boot:run

启动后,访问 http://localhost:8080/article,即可看到文章列表:

示例输出:
Article Title 0
Article Title 1
...


5. 处理默认值

在 Mustache 环境中,如果未为某个占位符提供值,将会抛出 MustacheException,提示类似 “No method or field with name ‘variable-name’…” 的错误。

为了避免此类错误,建议为所有占位符提供一个全局默认值:

@Bean
public Mustache.Compiler mustacheCompiler(
  Mustache.TemplateLoader templateLoader, 
  Environment environment) {

    MustacheEnvironmentCollector collector
      = new MustacheEnvironmentCollector();
    collector.setEnvironment(environment);

    return Mustache.compiler()
      .defaultValue("Some Default Value")
      .withLoader(templateLoader)
      .withCollector(collector);
}

6. 在 Spring MVC 中使用 Mustache(非 Spring Boot)

如果我们不使用 Spring Boot,而是使用传统的 Spring MVC,可以按如下方式集成 Mustache。

首先,添加依赖:

<dependency>
    <groupId>com.github.sps.mustache</groupId>
    <artifactId>mustache-spring-view</artifactId>
    <version>1.4</version>
</dependency>

最新版本请参考 Maven Central

接着,配置 MustacheViewResolver 替代 Spring 默认的 InternalResourceViewResolver

@Bean
public ViewResolver getViewResolver(ResourceLoader resourceLoader) {
    MustacheViewResolver mustacheViewResolver
      = new MustacheViewResolver();
    mustacheViewResolver.setPrefix("/WEB-INF/views/");
    mustacheViewResolver.setSuffix(".mustache");
    mustacheViewResolver.setCache(false);
    
    MustacheTemplateLoader mustacheTemplateLoader 
      = new MustacheTemplateLoader();
    mustacheTemplateLoader.setResourceLoader(resourceLoader);
    mustacheViewResolver.setTemplateLoader(mustacheTemplateLoader);
    
    return mustacheViewResolver;
}

只需配置模板存放路径(prefix)、模板文件后缀(suffix)以及负责加载模板的 templateLoader 即可。


7. 结论

在本篇快速教程中,我们探讨了如何在 Spring Boot 中使用 Mustache 模板:

  • 渲染 UI 中的集合元素;
  • 为变量提供默认值以避免异常;
  • 并简要介绍了在传统 Spring MVC 中通过 MustacheViewResolver 集成 Mustache 的方法。

Mustache 的简洁性和“无逻辑”特性使其成为构建清晰、可维护视图层的理想选择。