java stringtemplate模板引擎使用
Java StringTemplate (ST) 完整使用样例
下面是一个完整的 StringTemplate v4 (ST) 使用样例,展示了各种最佳实践和常见用法。
1. 基本设置和简单模板
import org.stringtemplate.v4.ST;
import org.stringtemplate.v4.STGroup;
import org.stringtemplate.v4.STGroupFile;
public class StringTemplateDemo {
public static void main(String[] args) {
// 1. 最简单的字符串模板
ST hello = new ST("Hello, <name>!");
hello.add("name", "World");
System.out.println(hello.render()); // 输出: Hello, World!
// 2. 使用模板组文件(最佳实践)
demoGroupFileTemplates();
// 3. 复杂模板示例
demoComplexTemplates();
// 4. 条件语句和循环
demoConditionalsAndLoops();
// 5. 模板继承和包含
demoTemplateInheritance();
}
// 剩余的方法将在下面展示...
}
2. 使用模板组文件 (推荐做法)
private static void demoGroupFileTemplates() {
// 从文件加载模板组 (推荐将模板放在单独文件中)
STGroup group = new STGroupFile("templates/demo.stg");
// 获取模板实例
ST userTemplate = group.getInstanceOf("userProfile");
userTemplate.add("name", "Alice");
userTemplate.add("age", 30);
userTemplate.add("email", "alice@example.com");
System.out.println("\n用户档案:");
System.out.println(userTemplate.render());
}
对应的 demo.stg
文件内容:
// 模板组文件 demo.stg
// 用户档案模板
userProfile(name, age, email) ::= <<
用户信息:
---------
姓名: <name>
年龄: <age>
邮箱: <email>
>>
// 另一个模板
welcome(user) ::= "欢迎, <user.name>! 您的会员级别是: <user.level>"
3. 复杂模板示例
private static void demoComplexTemplates() {
STGroup group = new STGroup('$', '$'); // 使用$作为分隔符
// 定义多行模板
group.defineTemplate("classDef",
"class $className$ {\n" +
" $fields; separator=\"\\n\"$\n" +
" \n" +
" $methods; separator=\"\\n\"$\n" +
"}");
group.defineTemplate("field", " private $type$ $name$;");
group.defineTemplate("method",
" public $returnType$ $name$($params$) {\n" +
" // 方法体\n" +
" }");
ST classTemplate = group.getInstanceOf("classDef");
classTemplate.add("className", "Person");
// 添加字段
ST field1 = group.getInstanceOf("field");
field1.add("type", "String");
field1.add("name", "firstName");
ST field2 = group.getInstanceOf("field");
field2.add("type", "String");
field2.add("name", "lastName");
classTemplate.add("fields", field1);
classTemplate.add("fields", field2);
// 添加方法
ST method1 = group.getInstanceOf("method");
method1.add("returnType", "String");
method1.add("name", "getFullName");
method1.add("params", "");
ST method2 = group.getInstanceOf("method");
method2.add("returnType", "void");
method2.add("name", "setName");
method2.add("params", "String firstName, String lastName");
classTemplate.add("methods", method1);
classTemplate.add("methods", method2);
System.out.println("\n生成的类:");
System.out.println(classTemplate.render());
}
4. 条件语句和循环
private static void demoConditionalsAndLoops() {
STGroup group = new STGroup();
// 定义带条件的模板
group.defineTemplate("employeeList",
"员工列表:\n" +
"<employees:{e | " +
"- <e.name> <if(e.manager)>(经理)<endif>\n" +
"}>");
ST listTemplate = group.getInstanceOf("employeeList");
// 创建员工数据
Employee[] employees = {
new Employee("张三", false),
new Employee("李四", true),
new Employee("王五", false)
};
listTemplate.add("employees", employees);
System.out.println("\n员工列表:");
System.out.println(listTemplate.render());
}
// 辅助类
static class Employee {
String name;
boolean manager;
public Employee(String name, boolean manager) {
this.name = name;
this.manager = manager;
}
public String getName() { return name; }
public boolean getManager() { return manager; }
}
5. 模板继承和包含
private static void demoTemplateInheritance() {
// 创建主模板组
STGroup group = new STGroup();
// 定义基础模板
group.defineTemplate("basePage",
"<html>\n" +
"<head>\n" +
" <title><pageTitle></title>\n" +
"</head>\n" +
"<body>\n" +
" <header>\n" +
" <include('header')>\n" +
" </header>\n" +
" \n" +
" <content>\n" +
" <pageContent>\n" +
" </content>\n" +
" \n" +
" <footer>\n" +
" <include('footer')>\n" +
" </footer>\n" +
"</body>\n" +
"</html>");
// 定义包含的模板
group.defineTemplate("header", "网站标题");
group.defineTemplate("footer", "© 2023 我的网站");
// 定义继承自basePage的具体页面
group.defineTemplate("homePage",
"<basePage()>\n" +
"<pageTitle: \"首页\">\n" +
"<pageContent: \"欢迎来到我们的网站!\">");
ST homePage = group.getInstanceOf("homePage");
System.out.println("\n生成的HTML页面:");
System.out.println(homePage.render());
}
6. 其他高级特性
private static void demoAdvancedFeatures() {
// 1. 使用匿名模板
ST anonymous = new ST("匿名模板: <items:{it|<it> }>");
anonymous.add("items", new String[]{"A", "B", "C"});
System.out.println("\n匿名模板结果: " + anonymous.render());
// 2. 使用模板参数
STGroup group = new STGroup();
group.defineTemplate("test", "参数1: <p1>, 参数2: <p2>");
ST test = group.getInstanceOf("test");
test.add("p1", "值1");
test.add("p2", "值2");
System.out.println("带参数模板: " + test.render());
// 3. 使用格式化函数
ST format = new ST("当前日期: <now; format=\"yyyy-MM-dd\">");
format.add("now", new java.util.Date());
System.out.println("格式化日期: " + format.render());
// 4. 多值属性
ST multi = new ST("名字: <names; separator=\", \">");
multi.add("names", "Alice");
multi.add("names", "Bob");
multi.add("names", "Charlie");
System.out.println("多值属性: " + multi.render());
}
最佳实践总结
-
模板组织:
- 将模板存储在单独的
.stg
文件中,而不是硬编码在Java中 - 按功能或模块组织模板组
- 将模板存储在单独的
-
模板设计:
- 保持模板简洁,避免复杂逻辑
- 使用模板继承和包含来重用公共部分
- 为常用模式创建可重用的小模板
-
数据准备:
- 在Java代码中准备好数据,模板只负责展示
- 使用POJO或Map作为数据模型
-
性能考虑:
- 重用STGroup实例,它内部会缓存模板
- 对于频繁使用的模板,考虑预编译
-
错误处理:
- 检查模板是否存在:
group.getInstanceOf("template")
返回null如果模板不存在 - 捕获并处理
STException
- 检查模板是否存在:
-
国际化:
- 为不同语言创建不同的模板组文件
- 根据语言环境加载相应的模板组
这个示例展示了StringTemplate v4的主要功能,包括简单和复杂模板、条件语句、循环、模板继承、格式化等。实际使用时,可以根据需要调整和扩展这些模式。
标题:java stringtemplate模板引擎使用
作者:michael
地址:https://blog.junxworks.cn/articles/2025/07/14/1752471250011.html