简体   繁体   English

如何使用字符串作为速度模板?

[英]How to use String as Velocity Template?

What is the best way to create Velocity Template from a String?从字符串创建速度模板的最佳方法是什么?

I'm aware of Velocity.evaluate method where I can pass String or StringReader, but I'm curios is there a better way to do it (eg any advantage of creating an instance of Template).我知道Velocity.evaluate方法,我可以在其中传递 String 或 StringReader,但我很好奇是否有更好的方法来做到这一点(例如,创建模板实例的任何优势)。

There is some overhead parsing template.有一些开销解析模板。 You might see some performance gain by pre-parsing the template if your template is large and you use it repeatedly.如果您的模板很大并且您反复使用它,您可能会通过预解析模板看到一些性能提升。 You can do something like this,你可以做这样的事情,

RuntimeServices runtimeServices = RuntimeSingleton.getRuntimeServices();
StringReader reader = new StringReader(bufferForYourTemplate);
Template template = new Template();
template.setRuntimeServices(runtimeServices);

/*
 * The following line works for Velocity version up to 1.7
 * For version 2, replace "Template name" with the variable, template
 */
template.setData(runtimeServices.parse(reader, "Template name")));

template.initDocument();

Then you can call template.merge() over and over again without parsing it everytime.然后你可以一遍又一遍地调用template.merge()而无需每次都解析它。

BTW, you can pass String directly to Velocity.evaluate() .顺便说一句,您可以将 String 直接传递给Velocity.evaluate()

The above sample code is working for me.上面的示例代码对我有用。 It uses Velocity version 1.7 and log4j.它使用 Velocity 1.7 版和 log4j。

private static void velocityWithStringTemplateExample() {
    // Initialize the engine.
    VelocityEngine engine = new VelocityEngine();
    engine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, "org.apache.velocity.runtime.log.Log4JLogChute");
    engine.setProperty("runtime.log.logsystem.log4j.logger", LOGGER.getName());
    engine.setProperty(Velocity.RESOURCE_LOADER, "string");
    engine.addProperty("string.resource.loader.class", StringResourceLoader.class.getName());
    engine.addProperty("string.resource.loader.repository.static", "false");
    //  engine.addProperty("string.resource.loader.modificationCheckInterval", "1");
    engine.init();

    // Initialize my template repository. You can replace the "Hello $w" with your String.
    StringResourceRepository repo = (StringResourceRepository) engine.getApplicationAttribute(StringResourceLoader.REPOSITORY_NAME_DEFAULT);
    repo.putStringResource("woogie2", "Hello $w");

    // Set parameters for my template.
    VelocityContext context = new VelocityContext();
    context.put("w", "world!");

    // Get and merge the template with my parameters.
    Template template = engine.getTemplate("woogie2");
    StringWriter writer = new StringWriter();
    template.merge(context, writer);

    // Show the result.
    System.out.println(writer.toString());
}

A similar so question.一个类似的问题。

This works in Velocity 2.1这适用于速度 2.1

// Initialize the engine
VelocityEngine velocityEngine = new VelocityEngine();
velocityEngine.setProperty(Velocity.RESOURCE_LOADERS, "string");
velocityEngine.setProperty("resource.loader.string.class", StringResourceLoader.class.getName());
velocityEngine.setProperty("resource.loader.string.cache", true);
velocityEngine.setProperty("resource.loader.string.modification_check_interval", 60);
velocityEngine.init();

// Add template to repository
StringResourceRepository repository = StringResourceLoader.getRepository()
repository.putStringResource("hello_world", "Hello $w");

// Set parameters
VelocityContext context = new VelocityContext();
context.put("w", "world!");

// Process the template
StringWriter writer = new StringWriter();
velocityEngine.getTemplate('hello_world').merge( context, writer );

System.out.println(writer.toString());

Velocity 2 can be integrated into the JSR223 Java Scripting Language Framework which make another option to transform string as a template: Velocity 2 可以集成到 JSR223 Java 脚本语言框架中,这提供了另一种将字符串转换为模板的选项:

ScriptEngineManager manager = new ScriptEngineManager();
manager.registerEngineName("velocity", new VelocityScriptEngineFactory());
ScriptEngine engine = manager.getEngineByName("velocity");


System.setProperty(VelocityScriptEngine.VELOCITY_PROPERTIES, "path/to/velocity.properties");
String script = "Hello $world";
Writer writer = new StringWriter();
engine.getContext().setWriter(writer);
Object result = engine.eval(script);
System.out.println(writer);
RuntimeServices rs = RuntimeSingleton.getRuntimeServices();            
StringReader sr = new StringReader("Username is $username");
SimpleNode sn = rs.parse(sr, "User Information");

Template t = new Template();
    t.setRuntimeServices(rs);
    t.setData(sn);
    t.initDocument();

VelocityContext vc = new VelocityContext();
vc.put("username", "John");

StringWriter sw = new StringWriter();
t.merge(vc, sw);

System.out.println(sw.toString());

If you are looking for just variable substitution then following works如果您只是在寻找变量替换,那么以下工作

public String velocityEvaluate(final String template, final NotificationDTO notificationDTO) {
    final Map<String, String> context = getContextMap(notificationDTO);
    final VelocityContext velocityContext = new VelocityContext(context);
    final StringWriter stringWriter = new StringWriter();
    final StringReader reader = new StringReader(template);
    Velocity.evaluate(velocityContext, stringWriter, "Velocity String Template Evaluation", reader);
    return stringWriter.toString();
}

In case if any one looking to transform from json string to json object, in that case, need to convert json string to JsonNode & store it in context.如果有人希望从 json 字符串转换为 json 对象,在这种情况下,需要将 json 字符串转换为 JsonNode 并将其存储在上下文中。 For Ex:例如:

String jsonDataAsString = "{"name": "Aps"}";
JsonNode nodes = new ObjectMapper().readTree(jsonDataAsString );
VelocityContext velocityContext = new VelocityContext();
velocityContext.put("root", nodes);

then in your template, you can refer originating data which are set as "root" via "$root."+property然后在您的模板中,您可以通过“$root.”+property 引用设置为“root”的原始数据

$root.name

Hope it helps someone.希望它可以帮助某人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM