Loading velocity template inside a jar file

匿名 (未验证) 提交于 2019-12-03 01:20:02

问题:

I have a project where I want to load a velocity template to complete it with parameters. The whole application is packaged as a jar file. What I initially thought of doing was this:

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

And this works fine when I run it in eclipse. However, once I package the program and try to run it using the command line I get an error because the file could not be found.

I imagine the problem is in this line:

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

Because in a jar the absolute file does not exist, since it's inside a zip, but I couldn't yet find a better way to do it.

Anyone has any ideas?

回答1:

If you want to use resources from classpath, you should use resource loader for classpath:

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


回答2:

Final code, developed using the ideas presented in both answers above:

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


回答3:

Unless JAR is exploded, you can't read the resource in JAR as file. Use an input stream.

See following code snippets,

    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:

To make Velocity look for the templates in classpath:

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


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!