2009-09-16 7 views
47

Quelle est la meilleure façon de créer un modèle de vélocité à partir d'une chaîne?Comment utiliser String comme modèle de vélocité?

Je suis au courant de Velocity.evaluate méthode où je peux passer chaîne ou StringReader, mais je suis curios est-il une meilleure façon de le faire (par exemple un avantage de créer une instance de modèle).

Répondre

64

Il existe un modèle d'analyse générale. Vous pourriez voir un gain de performance en pré-analysant le modèle si votre modèle est grand et que vous l'utilisez de manière répétée. Vous pouvez faire quelque chose comme ça,

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

Ensuite, vous pouvez appeler template.merge() encore et encore sans l'analyser à chaque fois. Par ailleurs, vous pouvez passer directement la chaîne à Velocity.evaluate().

+0

Exactement ce que je cherchais. Merci. Pour la référence d'autres personnes, runtimeServices est une instance de org.apache.velocity.runtime.RuntimeInstance – tomsame

+0

Manquant une ligne. Pour l'exhaustivité, je l'ai ajouté. –

+12

+1 pour la mention Velocity.Evaluate puisque c'est exactement ce que je cherchais. –

10

L'exemple de code ci-dessus fonctionne pour moi. Il utilise Velocity version 1.7 et 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()); 
} 

Une question donc similar.

+0

Wow, c'est une approche unique. comment la ressource de chargement du moteur de vitesse semble être implémentée en interne, la propriété "string.resource.loader.class" pourrait-elle changer? –

0

Velocity 2 peut être intégré dans le JSR223 Java Scripting Language Framework qui font une autre option pour transformer la chaîne comme modèle:

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