从外部加载 Freemarker 模板 classpath/jar
Loading Freemarker templates from outside classpath/jar
我正在尝试使用 FreeMarker 为在我的应用程序中工作的不同代理生成报告。我在网上看了看,但如果模板不在我项目的资源文件夹中,是否可以加载模板,我找不到任何地方。
当我的应用程序从我尝试使用的 *.jar 文件运行时:
public ReportTemplate(final String template_path)
throws TemplateException, IOException {
CFG.setDirectoryForTemplateLoading(new File("."));
CFG.setDefaultEncoding("UTF-8");
template = CFG.getTemplate(template_path);
}
然后在我传递模板的 conf 文件中:
parameters: {
report: /../test.ftl
}
*.jar 文件和模板在同一个文件夹中,但据我了解,我首先需要退出 jar 文件,然后去获取模板。
我想知道是否有一种简单的方法可以为 FreeMarker 加载模板,而无需将它们放在我项目的 /resources/ 文件夹中(这样当其他人使用该应用程序时,他可以设计自己的模板并将其复制到文件夹中)。
我也不想使用硬编码路径,例如“/tmp/”,这就是我使用“.”的原因。当前位置路径。
几乎可以从任何地方加载模板,也可以从多个位置加载模板。但我怀疑这里有一些误解。
只有一个 cfg.templateLoader
属性。 cfg.setDirectoryForTemplateLoading(dir)
只是shorthand对cfg.setTemplateLoader(new FileTemplateLoader(dir))
的方便,cfg.setClassForTemplateLoading(...)
只是shorthand对cfg.setTemplateLoader(new ClassTemplateLoader(...))
的方便。如果您需要使用这两种机制加载(从任意目录,以及从 Java 类路径上的 jar-s),那么您需要使用 cfg.setTemplateLoader(new MultiTemplateLoader(new TemplateLoader[] { new FileTemplateLoader(dir), new ClassTemplateLoader(...) }))
。现在如果你尝试加载 foo/bar.ftl
,首先 FileTemplateLoader
将尝试加载相对于它自己的基本目录的 foo/bar.ftl
,如果找不到,那么 ClassTemplateLoader
将尝试加载 foo/bar.ftl
相对于它自己的基础包。两个 TemplateLoader
-s 是完全独立的虚拟目录树,彼此不了解。只是 MultiTemplateLoader
通过我刚刚展示的回退机制将两棵树相互重叠。
另请注意,ClassTemplateLoader
不知道 jar 的位置,或者根本不知道是否涉及 jar-s。它只是请求 Java ClassLoader
来定位和加载资源。
另请注意,使用 new File(".")
通常不是一个好主意,因为在大多数应用程序中,您无法很好地控制创建 TemplateLoader
时的当前工作目录。通常你在一些配置文件中有一个绝对路径,或者它作为命令行参数传入。 FreeMarker 并不关心你是怎么做到的。
我正在尝试使用 FreeMarker 为在我的应用程序中工作的不同代理生成报告。我在网上看了看,但如果模板不在我项目的资源文件夹中,是否可以加载模板,我找不到任何地方。 当我的应用程序从我尝试使用的 *.jar 文件运行时:
public ReportTemplate(final String template_path)
throws TemplateException, IOException {
CFG.setDirectoryForTemplateLoading(new File("."));
CFG.setDefaultEncoding("UTF-8");
template = CFG.getTemplate(template_path);
}
然后在我传递模板的 conf 文件中:
parameters: {
report: /../test.ftl
}
*.jar 文件和模板在同一个文件夹中,但据我了解,我首先需要退出 jar 文件,然后去获取模板。 我想知道是否有一种简单的方法可以为 FreeMarker 加载模板,而无需将它们放在我项目的 /resources/ 文件夹中(这样当其他人使用该应用程序时,他可以设计自己的模板并将其复制到文件夹中)。 我也不想使用硬编码路径,例如“/tmp/”,这就是我使用“.”的原因。当前位置路径。
几乎可以从任何地方加载模板,也可以从多个位置加载模板。但我怀疑这里有一些误解。
只有一个 cfg.templateLoader
属性。 cfg.setDirectoryForTemplateLoading(dir)
只是shorthand对cfg.setTemplateLoader(new FileTemplateLoader(dir))
的方便,cfg.setClassForTemplateLoading(...)
只是shorthand对cfg.setTemplateLoader(new ClassTemplateLoader(...))
的方便。如果您需要使用这两种机制加载(从任意目录,以及从 Java 类路径上的 jar-s),那么您需要使用 cfg.setTemplateLoader(new MultiTemplateLoader(new TemplateLoader[] { new FileTemplateLoader(dir), new ClassTemplateLoader(...) }))
。现在如果你尝试加载 foo/bar.ftl
,首先 FileTemplateLoader
将尝试加载相对于它自己的基本目录的 foo/bar.ftl
,如果找不到,那么 ClassTemplateLoader
将尝试加载 foo/bar.ftl
相对于它自己的基础包。两个 TemplateLoader
-s 是完全独立的虚拟目录树,彼此不了解。只是 MultiTemplateLoader
通过我刚刚展示的回退机制将两棵树相互重叠。
另请注意,ClassTemplateLoader
不知道 jar 的位置,或者根本不知道是否涉及 jar-s。它只是请求 Java ClassLoader
来定位和加载资源。
另请注意,使用 new File(".")
通常不是一个好主意,因为在大多数应用程序中,您无法很好地控制创建 TemplateLoader
时的当前工作目录。通常你在一些配置文件中有一个绝对路径,或者它作为命令行参数传入。 FreeMarker 并不关心你是怎么做到的。