2010-06-11 138 views
29

我有一个web应用程序,我需要手动获取Freemarker模板 - 该模板是通过库项目中的类获取的,但实际的tpl文件包含在Web应用程序类路径中。所以,有两个项目,一个是'taac-backend-api',另一个是'taac-web'。 taac-backend-api具有获取模板并处理它的代码,但taac-web是模板存储的地方(具体位于:WEB-INF/classes/email/vendor.tpl) - 我尝试了使用将类路径资源弹出以使用Freemarkers setClassForTemplateLoading方法。我认为这将工作:从类路径设置freemarker模板

freemarkerConfiguration = new Configuration(); 
    freemarkerConfiguration.setClassForTemplateLoading(this.getClass(), ""); 
    Template freemarkerTemplate = freemarkerConfiguration.getTemplate("/email/vendor.tpl"); 

但是,我总是得到一个FileNotFoundException。有人可以解释从类路径获取模板的最佳方式吗?

谢谢。

回答

71

这是结束了,我的工作:

freemarkerConfiguration = new Configuration(); 
freemarkerConfiguration.setClassForTemplateLoading(this.getClass(), "/"); 
Template freemarkerTemplate = freemarkerConfiguration.getTemplate("email/vendor.tpl"); 
0

如果您正在使用Struts 2和公约的插件,wuntee的解决方案似乎不工作:依次setClassForTemplateLoading将创建其中没有按的ClassTemplateLoader实例无论指定什么路径前缀,都不会在jar中找到文件。

取而代之,创建一个StrutsClassTemplateLoader的实例。 (我在getTemplateLoader方法中的FreemarkerManager的自定义子类中执行此操作。)它不接受任何参数,因此大概只知道Struts和约定如何执行操作。

+0

根据类加载器层次结构,有时必须仔细考虑您为“ClassTemplateLoader”指定的类。通常最好的方法是使用'ClassTemplateLoader'构造函数,该构造函数直接使用'ClassLoader'(而不是'Class' - 自2.3.22开始),然后传入Web应用程序的线程上下文类加载器。 – ddekany 2015-03-14 09:49:53

3
freemarkerConfiguration = new Configuration(); 
freemarkerConfiguration.setClassForTemplateLoading(this.getClass(), ""); 
Template freemarkerTemplate = freemarkerConfiguration.getTemplate("template.tpl"); 

使用此方法来加载从那里类所在的包中的类,所以如果你的类是

org.foo.SomeClass模板将在/org/foo在类路径中寻找。这使您的模板与使用/加载它们的类一起存储。

3

在2017年,以下是弃用:

Configuration conf = new Configuration(); 

我们应该通过freemarker.template.Version的构造器:

Configuration conf = new Configuration(new Version(2, 3, 23)); 
conf.setClassForTemplateLoading(Application.class, "/views"); 

其中,版本号是指FreeMarker的当前版本。

views该目录位于src/main/resources