【问题标题】:Velocity Template File Resource Loader not working速度模板文件资源加载器不工作
【发布时间】:2019-03-17 21:07:44
【问题描述】:

面对一些奇怪的问题, 像这样设置 Velocity Engine。

 Properties properties = new Properties();
    properties.setProperty(RuntimeConstants.EVENTHANDLER_INCLUDE,IncludeRelativePath.class.getName());

    properties.setProperty(RuntimeConstants.RESOURCE_LOADER, "file");
    properties.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
    File f = new File(".");
    LOGGER.info("Base class path : {}",f.getCanonicalPath());
    //Objects.requireNonNull(resource);
    properties.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH,f.getCanonicalPath());
    VelocityEngine velocityEngine = new VelocityEngine();
    velocityEngine.init(properties);
    return velocityEngine;

然后我试图获取使用创建的文件:

PrintWriter out = new PrintWriter(templateName+".vm");
        out.println(fileContentStr);
        out.close();

像这样:

Template t = this.getEngine().getTemplate(  fileName + ".vm");

这给了我 ResourceNotFoundException。它在我的本地工作。我没有在任何地方对路径进行硬编码。无法理解为什么它不起作用。请有人可以在这里帮助我。在尝试了所有排列组合后我被卡住了。

Motive : 我只需要能够从项目目录中读取 VM 文件并创建一个。

【问题讨论】:

  • properties.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());这行没用,应该是properties.setProperty("file.resource.loader.class", FileResourceLoader.class.getName());。它至少在本地工作,因为这是此属性的默认值,这不是问题的原因。
  • 另外说明:IncludeRelativePath 的目的是让#include() 和#parse() 在与当前模板相同的目录中查找模板。它不适用于您的用例。
  • @ClaudeBrisson 给出了所有要点。我也想问一下模板名称对吗?因为在 windows templatename 不区分大小写的其他人不。如果生产的不是windows怎么办?
  • @soorapadman 你是对的,必须检查区分大小写。我将其添加到我的答案中。

标签: java velocity


【解决方案1】:

如果您确定工作目录在模板构建和读取之间没有变化,那么您在初始化 Velocity 之前不需要设置任何属性

  • 您不需要IncludeRelativePath,因为它的目的是让#include() 和#parse() 在与当前模板相同的目录中查找模板。它不适用于您的用例。
  • 您不需要设置 file 资源加载器,因为它是默认设置。
  • 您当然不需要设置 classpath 资源加载器的类,因为您甚至没有使用它
  • 您不需要设置文件资源加载器路径,因为它默认为“.”。

我不知道为什么您的代码在本地工作而不是在生产环境中工作。也许工作目录已更改。也许变量templateNamefileName 不一致。也许模板在编写之前就被要求了。环境之间是否有任何重大差异?有什么安全问题吗?操作系统是一样的吗?正如 soorapadman 所指出的,这可能是 linux 和 Windows 之间区分大小写的问题。

以下代码应该可以在任何地方工作:

VelocityEngine velocityEngine = new VelocityEngine();
velocityEngine.init();
PrintWriter out = new PrintWriter("test.vm");
out.println("hello");
out.close();
Template template = velocityEngine.getTemplate("test.vm");

【讨论】:

  • 环境有变化。我在本地使用 Linux 并在项目目录中创建文件。在服务器中,我们使用的是 Kubernetes,所以当我尝试执行“.”.getCanonicalPath() 时,它给了我“/”,而当我使用 ec2 时,它给了我正确的 spring/boot 路径,因此找到了模板。有没有人遇到过这个?另外,如果我使用文件资源加载器和 ClasspathResourceLoader,那么我的引擎会从这两个地方读取吗?
  • 要同时使用两个类加载器,你必须设置resource.loader = file, classpath(或者相反,取决于你想要的优先级),然后指定它们的属性:file.resource.loader.classfile.resource.loader.path(可以包含多条路径)和classpath.resource.loader.class.
猜你喜欢
  • 2012-12-26
  • 2011-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-12
相关资源
最近更新 更多