Handlebars 是一个轻量级的模板引擎,适用于 Java 项目中的动态内容生成。本文将介绍 Handlebars.java 的基本使用方法,包括模板定义、上下文传值、内置助手、自定义助手以及模板复用等内容。
1. 引入 Maven 依赖
使用 Handlebars 之前,需要先引入其 Maven 依赖:
<dependency>
<groupId>com.github.jknack</groupId>
<artifactId>handlebars</artifactId>
<version>4.3.1</version>
</dependency>
2. 简单模板使用
Handlebars 模板本质上是文本文件,通过 {{变量名}}
或 {{#each 变量}}
等标签进行动态内容替换。
我们可以通过 Map
、普通对象或字符串作为上下文传入模板。
2.1 使用 this
传递字符串
当上下文是一个字符串时,可以使用 {{this}}
替换:
@Test
public void whenThereIsNoTemplateFile_ThenCompilesInline() throws IOException {
Handlebars handlebars = new Handlebars();
Template template = handlebars.compileInline("Hi {{this}}!");
String templateString = template.apply("Baeldung");
assertThat(templateString).isEqualTo("Hi Baeldung!");
}
✅ 注意:compileInline
方法用于直接编译字符串模板。
2.2 使用 Map 作为上下文
使用 Map 传值时,模板中应使用对应的 key 名:
@Test
public void whenParameterMapIsSupplied_thenDisplays() throws IOException {
Handlebars handlebars = new Handlebars();
Template template = handlebars.compileInline("Hi {{name}}!");
Map<String, String> parameterMap = new HashMap<>();
parameterMap.put("name", "Baeldung");
String templateString = template.apply(parameterMap);
assertThat(templateString).isEqualTo("Hi Baeldung!");
}
✅ 注意:模板中 {{name}}
对应 Map 中的 "name"
键。
2.3 使用自定义对象作为上下文
Handlebars 也支持使用 POJO 作为上下文对象:
public class Person {
private String name;
private boolean busy;
private Address address = new Address();
private List<Person> friends = new ArrayList<>();
public static class Address {
private String street;
}
// Getter/Setter 省略
}
@Test
public void whenParameterObjectIsSupplied_ThenDisplays() throws IOException {
Handlebars handlebars = new Handlebars();
Template template = handlebars.compileInline("Hi {{name}}!");
Person person = new Person();
person.setName("Baeldung");
String templateString = template.apply(person);
assertThat(templateString).isEqualTo("Hi Baeldung!");
}
✅ 注意:{{name}}
会自动调用 person.getName()
获取值。
3. 模板加载器(Template Loaders)
Handlebars 支持从外部文件加载模板,常见的加载方式有:
- 类路径(classpath)
- 文件系统
- Servlet 上下文
3.1 默认模板加载器
默认情况下,Handlebars 会从类路径中加载模板:
@Test
public void whenNoLoaderIsGiven_ThenSearchesClasspath() throws IOException {
Handlebars handlebars = new Handlebars();
Template template = handlebars.compile("greeting");
Person person = new Person();
person.setName("Baeldung");
String templateString = template.apply(person);
assertThat(templateString).isEqualTo("Hi Baeldung!");
}
⚠️ 注意:compile("greeting")
会尝试加载类路径下的 greeting.hbs
文件。
3.2 自定义模板加载器
可以通过 ClassPathTemplateLoader
设置模板路径和后缀:
@Test
public void whenClasspathTemplateLoaderIsGiven_ThenSearchesClasspathWithPrefixSuffix() throws IOException {
TemplateLoader loader = new ClassPathTemplateLoader("/handlebars", ".html");
Handlebars handlebars = new Handlebars(loader);
Template template = handlebars.compile("greeting");
// ... 其他逻辑不变
}
✅ 此时会加载 /handlebars/greeting.html
。
3.3 多个加载器串联
可以设置多个加载器,按顺序查找模板:
@Test
public void whenMultipleLoadersAreGiven_ThenSearchesSequentially() throws IOException {
TemplateLoader firstLoader = new ClassPathTemplateLoader("/handlebars", ".html");
TemplateLoader secondLoader = new ClassPathTemplateLoader("/templates", ".html");
Handlebars handlebars = new Handlebars().with(firstLoader, secondLoader);
// ...
}
4. 内置助手(Built-in Helpers)
Handlebars 提供了一些内置助手来增强模板功能,常见的有:
4.1 with
助手
{{#with}}
用于改变当前上下文:
{{#with address}}
<h4>I live in {{street}}</h4>
{{/with}}
Java 示例:
@Test
public void whenUsedWith_ThenContextChanges() throws IOException {
Handlebars handlebars = new Handlebars(templateLoader);
Template template = handlebars.compile("with");
Person person = new Person();
person.setName("Baeldung");
person.getAddress().setStreet("World");
String templateString = template.apply(person);
assertThat(templateString).contains("<h4>I live in World</h4>");
}
4.2 each
助手
{{#each}}
用于遍历集合:
{{#each friends}}
<span>{{name}} is my friend.</span>
{{/each}}
Java 示例:
@Test
public void whenUsedEach_ThenIterates() throws IOException {
Handlebars handlebars = new Handlebars(templateLoader);
Template template = handlebars.compile("each");
Person person = new Person();
person.setName("Baeldung");
person.getFriends().add(new Person("Java"));
person.getFriends().add(new Person("Spring"));
String templateString = template.apply(person);
assertThat(templateString)
.contains("<span>Java is my friend.</span>", "<span>Spring is my friend.</span>");
}
4.3 if
助手
{{#if}}
用于条件判断:
{{#if busy}}
<h4>{{name}} is busy.</h4>
{{else}}
<h4>{{name}} is not busy.</h4>
{{/if}}
Java 示例:
@Test
public void whenUsedIf_ThenPutsCondition() throws IOException {
Handlebars handlebars = new Handlebars(templateLoader);
Template template = handlebars.compile("if");
Person person = new Person();
person.setName("Baeldung");
person.setBusy(true);
String templateString = template.apply(person);
assertThat(templateString).contains("<h4>Baeldung is busy.</h4>");
}
5. 自定义助手(Custom Helpers)
除了内置助手,我们还可以自定义模板助手。
5.1 实现 Helper
接口
handlebars.registerHelper("isBusy", new Helper<Person>() {
@Override
public Object apply(Person context, Options options) throws IOException {
String busyString = context.isBusy() ? "busy" : "available";
return context.getName() + " - " + busyString;
}
});
模板中使用:
{{#isBusy this}}{{/isBusy}}
5.2 使用 Helper Source 类
可以定义多个助手方法在一个类中,通过反射注册:
public class HelperSource {
public String isBusy(Person context) {
String busyString = context.isBusy() ? "busy" : "available";
return context.getName() + " - " + busyString;
}
}
注册方法:
handlebars.registerHelpers(new HelperSource());
6. 模板复用
Handlebars 提供了两种模板复用机制:
6.1 模板包含(Inclusion)
通过 {{>模板名}}
包含其他模板:
<!-- header.html -->
<h4>Hi {{name}}!</h4>
<!-- page.html -->
{{>header}}
<p>This is the page {{name}}</p>
Java 示例:
@Test
public void whenOtherTemplateIsReferenced_ThenCanReuse() throws IOException {
Handlebars handlebars = new Handlebars(templateLoader);
Template template = handlebars.compile("page");
Person person = new Person();
person.setName("Baeldung");
String templateString = template.apply(person);
assertThat(templateString)
.contains("<h4>Hi Baeldung!</h4>", "<p>This is the page Baeldung</p>");
}
6.2 模板继承(Inheritance)
使用 {{#block}}
和 {{#partial}}
实现模板继承:
<!-- messagebase.html -->
<html>
<body>
{{#block "intro"}}
This is the intro
{{/block}}
{{#block "message"}}
{{/block}}
</body>
</html>
<!-- simplemessage.html -->
{{#partial "message" }}
Hi there!
{{/partial}}
{{> messagebase}}
7. 小结
本文介绍了 Handlebars.java 的基本使用方式,包括:
- 模板编写与上下文传值
- 模板加载器的配置
- 内置助手的使用
- 自定义助手的实现
- 模板复用技巧(包含与继承)
Handlebars 是一个轻量级但功能强大的模板引擎,非常适合用于 Java 项目中的动态内容生成,尤其适合前后端分离或需要模板渲染的场景。