La velocidad de carga de la plantilla dentro de un archivo jar

Tengo un proyecto donde quiero cargar una velocidad de plantilla para completar con parámetros. Toda la aplicación está empaquetado como un archivo jar. Lo que inicialmente se pensó en hacerlo fue este:

VelocityEngine ve = new VelocityEngine();

   URL url = this.getClass().getResource("/templates/");

   File file = new File(url.getFile());

   ve = new VelocityEngine();
   ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "file");
   ve.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, file.getAbsolutePath());
   ve.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_CACHE, "true");

   ve.init();

   VelocityContext context = new VelocityContext();

   if (properties != null) {
    stringfyNulls(properties);
    for (Map.Entry<String, Object> property : properties.entrySet()) {
     context.put(property.getKey(), property.getValue());
    }
   }

   final String templatePath = templateName + ".vm";
   Template template = ve.getTemplate(templatePath, "UTF-8");
   String outFileName = File.createTempFile("report", ".html").getAbsolutePath();
   BufferedWriter writer = new BufferedWriter(new FileWriter(new File(outFileName)));

   template.merge(context, writer);

   writer.flush();
   writer.close();

Y esto funciona bien cuando lo ejecuto en eclipse. Sin embargo, una vez que el paquete del programa y tratar de ejecutarlo desde la línea de comandos me sale un error porque el archivo no se pudo encontrar.

Me imagino que el problema está en esta línea:

ve.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, file.getAbsolutePath());

Porque en un frasco el archivo absoluta no existe, ya que es dentro de un zip, pero no pude encontrar una mejor manera de hacerlo.

Alguien tiene alguna idea?

  • por el amor de dios, resalte el código en tu post y haga clic en el botón de código de modo que su formato adecuado! 🙂
  • Está usted muy seguro de que el /templates/ se exportan en el frasco? Usted tiene que marcar como parte de su configuración de generación y esas cosas.
  • no sabe sobre el botón de código, gracias. Sí, las plantillas de directorios es entrar en el archivo jar.
InformationsquelleAutor Rafael | 2010-05-28

5 Kommentare

  1. 72

    Si usted desea utilizar recursos de classpath, usted debe utilizar cargador de recursos para classpath:

    ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); 
    ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
    • Voy a probar! ¿sabes donde puedo encontrar documentación para cada RuntimeContants y sus posibles valores?
    • No podía hacer el trabajo, no encuentra el archivo en ninguno de eclipse ni en el frasco.
    • Fijo. ClasspathResourceLoader no registrados de forma predeterminada.
    • Gracias, funcionó cuando yo este de acuerdo con la idea presentada por ZZ Coder a continuación.
    • Funciona como escrita con v 1.7. Gracias. ` VelocityEngine ve = new VelocityEngine(); cinco.setProperty(RuntimeConstants.RESOURCE_LOADER, «classpath»); cinco.setProperty(«classpath.resource.loader.class», ClasspathResourceLoader.clase.getName()); cinco.init(); `
    • También mirar a los cinco.evaluar(..) lo que permite un java.io.Lector a ser pasado
    • Es lamentable que Javadocs de ClasspathResourceLoader, erróneamente, dice que el cargador de recursos de valor debe ser «de clase» – ya lo intenté y no funcionó, sólo para descubrir más tarde que debería ser «classpath» como se menciona en esta respuesta

  2. 20

    Final del código, desarrollado con las ideas presentadas en los dos respuestas anteriores:

    VelocityEngine ve = new VelocityEngine();
    ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
    ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
    
    ve.init();
    
    final String templatePath = "templates/" + templateName + ".vm";
    InputStream input = this.getClass().getClassLoader().getResourceAsStream(templatePath);
    if (input == null) {
        throw new IOException("Template file doesn't exist");
    }
    
    InputStreamReader reader = new InputStreamReader(input);
    
    VelocityContext context = new VelocityContext();
    
    if (properties != null) {
        stringfyNulls(properties);
        for (Map.Entry<String, Object> property : properties.entrySet()) {
            context.put(property.getKey(), property.getValue());
        }
    }
    
    Template template = ve.getTemplate(templatePath, "UTF-8");
    String outFileName = File.createTempFile("report", ".html").getAbsolutePath();
    BufferedWriter writer = new BufferedWriter(new FileWriter(new File(outFileName)));
    
    if (!ve.evaluate(context, writer, templatePath, reader)) {
        throw new Exception("Failed to convert the template into html.");
    }
    
    template.merge(context, writer);
    
    writer.flush();
    writer.close();
    • Gracias, esto me ha ayudado mucho! Podría ser que mi adapation funciona un poco diferente, pero el uso de VelocityEngine#evaluar(…), yo podría dejar fuera de la instancia de la Plantilla y la llamada a la Plantilla#de mezcla(…)
    • funciona como un encanto. El RuntimeInstance resuelto mi problema, lo que me permite cargar la plantilla en mi paquete. La mejor solución para OSGI
  3. 9

    Menos FRASCO está explotado, no se puede leer el recurso en el FRASCO como archivo. El uso de un flujo de entrada.

    Ver siguientes fragmentos de código,

        InputStream input = classLoader.getResourceAsStream(fileName);
        if (input == null) {
            throw new ConfigurationException("Template file " +
                    fileName + " doesn't exist");           
        }
    
        InputStreamReader reader = new InputStreamReader(input);            
            Writer writer = null;
    
            try {
                writer = new OutputStreamWriter(output);        
    
                //Merge template
                if (!engine.evaluate(context, writer, fileName, reader)) 
                    ......
  4. 0

    Para hacer que la Velocidad de buscar las plantillas en el classpath:

    VelocityEngine ve = new VelocityEngine();
    ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
    ve.setProperty("classpath.resource.loader.class",ClasspathResourceLoader.class.getName());
    ve.init();
    • Que se ve exactamente como la aceptación de la respuesta.
    • Creo que eres un poco tarde a la fiesta.
  5. 0

    Tal vez tengo una versión antigua, esta es la única cosa que trabajó para mí

    ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "class"); 
    ve.setProperty("classpath.resource.loader.class", 
    ClasspathResourceLoader.class.getName());

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea