【问题标题】:Setting freemarker template from classpath从类路径设置 freemarker 模板
【发布时间】:2011-03-02 10:57:50
【问题描述】:

我有一个需要手动获取 Freemarker 模板的 Web 应用程序 - 该模板是通过库项目中的类获得的,但实际的 tpl 文件包含在 Web 应用程序类路径中。因此,有 2 个项目,一个 'taac-backend-api' 和另一个 'taac-web'; taac-backend-api 具有获取模板并对其进行处理的代码,但 taac-web 是存储模板的位置(特别是在:WEB-INF/classes/email/vendor.tpl) - 我已经尝试过使用弹簧类路径资源使用 Freemarkers setClassForTemplateLoading 方法。我认为这会起作用:

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

然而,我总是收到 FileNotFoundException。有人可以解释从类路径获取模板的最佳方法吗?

谢谢。

【问题讨论】:

    标签: freemarker


    【解决方案1】:

    这就是最终对我有用的东西:

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

    【讨论】:

    • 请假设“email/vendor.tpl”在哪里?
    【解决方案2】:

    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

    【讨论】:

      【解决方案3】:
      freemarkerConfiguration = new Configuration();
      freemarkerConfiguration.setClassForTemplateLoading(this.getClass(), "");
      Template freemarkerTemplate = freemarkerConfiguration.getTemplate("template.tpl");
      

      使用这个方法从你的类所在的包中加载类,所以如果你的类是

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

      【讨论】:

      • 但是如果我想将模板保存在资源/模板文件夹下,我该怎么做呢?
      • @Aromal 找到解决方案了吗?
      【解决方案4】:

      如果您使用的是 Struts 2 和 Conventions 插件,wuntee 的解决方案似乎不起作用:setClassForTemplateLoading 反过来创建了一个 ClassTemplateLoader 的实例,无论指定什么路径前缀,它都不会在 jar 中找到文件.

      相反,创建StrutsClassTemplateLoader 的实例。 (我在其getTemplateLoader 方法中的FreemarkerManager 的自定义子类中执行此操作。)它不接受任何参数,所以大概它只知道Struts 和Conventions 是如何做事的。

      【讨论】:

      • 根据类加载器层次结构,有时必须仔细考虑您为ClassTemplateLoader 指定的类。通常最好使用ClassTemplateLoader 构造函数,该构造函数直接采用ClassLoader(而不是Class - 自2.3.22 起),然后传入Web 应用程序的线程上下文类加载器。
      【解决方案5】:

      使用以下配置并将其放在应用程序属性中。

      spring.freemarker.template-loader-path=
      

      【讨论】:

        猜你喜欢
        • 2015-09-11
        • 2021-01-26
        • 2012-09-07
        • 1970-01-01
        • 2021-05-11
        • 2014-09-15
        • 2013-04-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多