是否可以动态地互换使用多个项目中的Freemarker模板?

时间:2019-04-09 10:40:56

标签: java spring-boot dependency-injection freemarker contextpath

我有2个项目。 Project A 是一个Spring Boot应用程序,主要致力于编辑和更新信息。 项目B 具有查看信息的方法,我正在尝试将其用作( A )的依赖项,以最大程度地重复使用代码并最大程度地减少修复任何错误/多次进行任何改进。

我希望能够让我的控制器和模板正确地动态找到正确的模板。

项目A 正确使用了项目B 依赖项中包含的任何服务/内容,但我在使前端播放效果方面遇到问题。过去,我有一个项目没有自己的前端使用,而在第二个项目中定义了模板。这就像在我的配置中的Freemarker TemplateLoaderPath上设置正确的@Bean一样简单。这次,我怀疑一旦调用了 Project A 本地的模板,它将假定在该上下文路径中也可以找到任何后续模板,而不会在 Project B中查找

对我来说,稍微显示一下项目的结构可能会更容易:

src/main/resources/ templates/ feature1/ f1page.ftl feature2/ f2page.ftl Maven Dependencies projectB.jar templates/ feature3/ f3page.ftl feature4/ f4page.ftl

我希望当我为我的控制器返回新的ModelAndView对象时

return new ModelAndView("feature3/f3page.ftl");

return new ModelAndView("feature1/f1page.ftl");,因为这两个功能文件夹都位于templates/中,但位置不同。

值得一提的是,正在进行大量的模板导入,因此找到合适的模板也需要在这里工作。因此,如果f1page.ftl(在src / main / resources中)具有以下行:

<#import "feature3/f3page.ftl" as f3>,需要在其他位置(依赖项.jar内)找到。

下面是此示例中当前freemarker堆栈跟踪的示例。返回时似乎找到了f1page.ftlnew ModelAndView("feature1/f1page.ftl");,但是找不到第2行上的导入内容feature3/f3page.ftl

Template importing failed (for parameter value "/feature3/f3page.ftl"): Template not found for name "/feature3/f3page.ftl". The name was interpreted by this TemplateLoader: MultiTemplateLoader(loader1 = FileTemplateLoader(baseDir="C:\Users\Becxxxa\Projects\ProjectA\target\classes\templates", canonicalBasePath="C:\Users\Becxxxa\Projects\ProjectA\target\classes\templates\"), loader2 = ClassTemplateLoader(resourceLoaderClass=org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer, basePackagePath="" /* relatively to resourceLoaderClass pkg */)). ---- FTL stack trace ("~" means nesting-related): - Failed at: #import "/feature3/f3page.ftl" as f3 [in template "feature1/f1page.ftl" at line 2, column 1]

这是我的@Bean,如您所见,我已将setPreferFileSystemAccess应用于false(如建议的here),但无济于事。

@Bean public FreeMarkerConfigurationFactoryBean getFreeMarkerConfiguration() { FreeMarkerConfigurationFactoryBean bean = new FreeMarkerConfigurationFactoryBean(); bean.setTemplateLoaderPath("classpath:/templates/"); bean.setPreferFileSystemAccess(false); return bean; }

我可能对Freemarker的要求过多,这实际上是不可能的。但是,如果不是这样,我需要帮助正确配置我的项目/ freemarker以与两种模板源一起动态工作。我觉得我可能缺少有关模板加载的明显提示。

1 个答案:

答案 0 :(得分:1)

感谢@Taylor O'Connor,虽然这不是解决方案,但我认为我一直在寻找针对似乎是复杂问题的简单解决方案。

我最终使用maven-dependency-plugin将依赖关系所需的模板解压缩到父项目的src / main / resources / templates文件夹中。这满足了我不必维护同一代码的多个源的要求。

这是我添加到pom中的插件:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>unpack</id>
            <phase>package</phase>
            <goals>
                <goal>unpack</goal>
            </goals>
            <configuration>
            <artifactItems>
                <artifactItem>
                    <groupId>uk.co.company</groupId>
                    <artifactId>projectA</artifactId>
                    <outputDirectory>src/main/resources/</outputDirectory>
                    <includes>templates/feature3/**</includes>
                    <excludes>*/feature4/*</excludes>
                </artifactItem>
            </artifactItems>
            </configuration>
        </execution>
    </executions>
</plugin>

这会将feature3文件夹放入我的templates文件夹中。我必须排除feature4,因为它与我的模板文件夹中已经存在的文件夹名称匹配,这对我来说是最好的,因为模板必须略有不同,因为其中包含我的“ layout.ftl”,但确实有所不同在应用程序之间略微切换。