java 在jar文件中加载velocity模板

brgchamk  于 2023-04-28  发布在  Java
关注(0)|答案(5)|浏览(221)

我有一个项目,我想加载一个速度模板完成它的参数。整个应用程序被打包为一个jar文件。我最初想做的是这样的:

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

当我在eclipse中运行时,这个工作得很好。然而,一旦我打包程序并尝试使用命令行运行它,我得到一个错误,因为文件找不到。
我想问题出在这一行:

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

因为在jar中绝对文件是不存在的,因为它在zip中,但是我还没有找到更好的方法。
有人有什么想法吗?

hujrc8aj

hujrc8aj1#

如果你想使用classpath中的资源,你应该使用classpath的资源加载器:

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

btxsgosb2#

最终代码,使用上面两个答案中提出的想法开发:

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

watbbzwu3#

除非JAR被分解,否则您不能将JAR中的资源作为文件读取。使用输入流。
请参阅以下代码片段,

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)) 
                ......
xqk2d5yq

xqk2d5yq4#

要使Velocity在类路径中查找模板,请执行以下操作:

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

ajsxfq5m5#

也许我有一个旧版本,这是唯一对我有效的东西

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

相关问题