2009-09-16 16 views
47

¿Cuál es la mejor manera de crear una Plantilla de Velocidad desde una Cadena?¿Cómo se usa String como Velocity Template?

Soy consciente de Velocity.evaluate método donde puedo pasar Cadena o StringReader, pero estoy curios hay una mejor manera de hacerlo (por ejemplo, cualquier ventaja de crear una instancia de plantilla).

Respuesta

64

Hay una plantilla de análisis de gastos indirectos. Es posible que vea cierta ganancia de rendimiento al analizar previamente la plantilla si su plantilla es grande y la usa repetidamente. Se puede hacer algo como esto,

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

A continuación, puede llamar template.merge() una y otra vez sin necesidad de analizar cada vez.

Por cierto, puede pasar String directamente al Velocity.evaluate().

+0

Exactamente lo que estaba buscando. Gracias. Para referencia de otras personas, runtimeServices es una instancia de org.apache.velocity.runtime.RuntimeInstance – tomsame

+0

Perdida de una línea. Para completar, lo agregué. –

+12

+1 por la mención de Velocity. Evaluar ya que eso es exactamente lo que estaba buscando. –

10

El código de ejemplo anterior funciona para mí. Utiliza Velocity versión 1.7 y 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 pregunta.

+0

Guau, este es un enfoque único. cómo el recurso de carga del motor de velocidad parece ser una implementación interna, ¿podría la propiedad "string.resource.loader.class" estar sujeta a cambios? –

0

velocidad 2 se puede integrar en el JSR223 Java Scripting Language Framework que hacen otra opción para transformar cadena como una plantilla:

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