java stringtemplate模板引擎使用

  |   0 评论   |   0 浏览

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());
}

最佳实践总结

  1. 模板组织:

    • 将模板存储在单独的 .stg 文件中,而不是硬编码在Java中
    • 按功能或模块组织模板组
  2. 模板设计:

    • 保持模板简洁,避免复杂逻辑
    • 使用模板继承和包含来重用公共部分
    • 为常用模式创建可重用的小模板
  3. 数据准备:

    • 在Java代码中准备好数据,模板只负责展示
    • 使用POJO或Map作为数据模型
  4. 性能考虑:

    • 重用STGroup实例,它内部会缓存模板
    • 对于频繁使用的模板,考虑预编译
  5. 错误处理:

    • 检查模板是否存在: group.getInstanceOf("template") 返回null如果模板不存在
    • 捕获并处理 STException
  6. 国际化:

    • 为不同语言创建不同的模板组文件
    • 根据语言环境加载相应的模板组

这个示例展示了StringTemplate v4的主要功能,包括简单和复杂模板、条件语句、循环、模板继承、格式化等。实际使用时,可以根据需要调整和扩展这些模式。


标题:java stringtemplate模板引擎使用
作者:michael
地址:https://blog.junxworks.cn/articles/2025/07/14/1752471250011.html