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 的简洁性和“无逻辑”特性使其成为构建清晰、可维护视图层的理想选择。