【问题标题】:How to use String as Velocity Template?如何使用字符串作为速度模板?
【发布时间】:2009-09-16 11:44:14
【问题描述】:

从字符串创建 Velocity 模板的最佳方法是什么?

我知道 Velocity.evaluate 方法可以传递 String 或 StringReader,但我很好奇有没有更好的方法来做到这一点(例如,创建模板实例的任何优势)。

【问题讨论】:

    标签: java velocity


    【解决方案1】:

    有一些开销解析模板。如果您的模板很大并且您反复使用它,您可能会通过预解析模板看到一些性能提升。你可以这样做,

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

    然后你可以一遍又一遍地调用template.merge(),而不用每次都解析它。

    顺便说一句,您可以将字符串直接传递给Velocity.evaluate()

    【讨论】:

    • 正是我想要的。谢谢。供其他人参考,runtimeServices 是 org.apache.velocity.runtime.RuntimeInstance 的一个实例
    • 漏了一行。为了完整起见,我添加了它。
    • +1 提到 Velocity.Evaluate 因为这正是我想要的。
    • 括号过多导致编译错误。应该是template.setData(runtimeServices.parse(reader, "Template name")); stackoverflow 抱怨Edits must be at least 6 characters; is there something else to improve in this post?
    【解决方案2】:

    上面的示例代码对我有用。它使用 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());
    }
    

    similar 这样的问题。

    【讨论】:

    • 哇,这是一种独特的方法。速度引擎负载资源似乎是内部实现,属性“string.resource.loader.class”是否会发生变化?
    【解决方案3】:

    这适用于 Velocity 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.RESOURCE_LOADERS 中有错字 - 应该是Velocity.RESOURCE_LOADER
    • Velocity 类实现的RuntimeConstants 接口有两个常量——RESOURCE_LOADERSRESOURCE_LOADERRESOURCE_LOADERS 是我测试过的那个
    • 这对我有用了一段时间。但后来我在日志文件中发现了内部速度异常。我更改为以下解决方案,现在一切正常:Velocity template as a String in Java。它使用Velocity#evaluate(context, out, logTag, instring),正如此处另一个答案所述。
    【解决方案4】:

    Velocity 2 可以集成到 JSR223 Java Scripting Language Framework 中,这使得另一个选项可以将字符串转换为模板:

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

    【讨论】:

      【解决方案5】:
      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());
      

      【讨论】:

        【解决方案6】:

        如果您只是在寻找变量替换,那么以下工作

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-11-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多