我正在尝试使用 freemarker 来模板化我的 java 类。
我的配置bean是:
@Bean
public FreeMarkerConfigurer freeMarkerConfigurer() {
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
String[] paths = Stream.of(
"classpath:/templates",
"classpath:/templates/dao/",
"classpath:/templates/pom/",
"classpath:/common/")
.map(path -> path.replace("/", File.separator).replace("\\", File.separator))
.toArray(String[]::new);
configurer.setTemplateLoaderPaths(paths);
configurer.setDefaultEncoding("UTF-8");
configurer.setPostTemplateLoaders();
return configurer;
}
我的模板文件 Type.ftl :
<#import "/common/functions.ftl" as function>
<#assign className = "${data.className}">
<#assign typeName = "${function.camelToSnakeCase(data.className)}">
<#assign packagePath = structure.packagePathPrefix + "." + structure.module?replace("-", ".") + ".core.dao.udt">
package ${packagePath};
@Data
@AllArgsConstructor
@NoArgsConstructor(force = true)
@Builder(toBuilder = true)
@UserDefinedType("${typeName}")
public class ${className} {
<#list data.columns as column>
@Column("${column.name}")
private ${column.dataType} ${column.name?uncap_first};
</#list>
}
如果我从当前目录引用我的 function.ftl ,它会起作用,但当我从 commons/functions.ftl 引用它时,它会失败。我必须使用 /common/functions.ftl 中的常用函数,以便所有模板都可以使用常用函数。但我的模板给出了以下错误:
2024-02-27T14:44:54.793-06:00 ERROR 58803 --- [nio-8090-exec-1] freemarker.runtime : Error executing FreeMarker template
freemarker.core._MiscTemplateException: Template importing failed (for parameter value "/common/functions.ftl"):
Template not found for name "common/functions.ftl".
The name was interpreted by this TemplateLoader: MultiTemplateLoader(loader1 = org.springframework.ui.freemarker.SpringTemplateLoader@4f1fb188, loader2 = ClassTemplateLoader(resourceLoaderClass=org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer, basePackagePath="" /* relatively to resourceLoaderClass pkg */)).
----
FTL stack trace ("~" means nesting-related):
- Failed at: #import "/common/functions.ftl" as fu... [in template "dao/udt/Type.ftl" at line 3, column 1]
----
at freemarker.core.LibraryLoad.accept(LibraryLoad.java:67) ~[freemarker-2.3.32.jar:2.3.32]
at freemarker.core.Environment.visit(Environment.java:335) ~[freemarker-2.3.32.jar:2.3.32]
at freemarker.core.Environment.visit(Environment.java:341) ~[freemarker-2.3.32.jar:2.3.32]
at freemarker.core.Environment.process(Environment.java:314) ~[freemarker-2.3.32.jar:2.3.32]
at freemarker.template.Template.process(Template.java:383) ~[freemarker-2.3.32.jar:2.3.32]
at org.springframework.ui.freemarker.FreeMarkerTemplateUtils.processTemplateIntoString(FreeMarkerTemplateUtils.java:50) ~[spring-context-support-6.1.3.jar:6.1.3]
我尝试了相对路径:
<#import "../../../common/functions.ftl" as function>
但是你又遇到错误了:
2024-02-27T14:55:44.552-06:00 ERROR 60233 --- [nio-8090-exec-1] freemarker.runtime : Error executing FreeMarker template
freemarker.core._MiscTemplateException: Template importing failed (for parameter value "../../../common/functions.ftl"):
Template not found for name "dao/udt/../../../common/functions.ftl".
Reason given: Backing out from the root directory is not allowed.
The name was interpreted by this TemplateLoader: MultiTemplateLoader(loader1 = FileTemplateLoader(baseDir="/Users/rahulverma/git/by-rahul/one-click-code/template-services-code-core/target/classes/templates", canonicalBasePath="/Users/rahulverma/git/by-rahul/one-click-code/template-services-code-core/target/classes/templates/"), loader2 = FileTemplateLoader(baseDir="/Users/rahulverma/git/by-rahul/one-click-code/template-services-code-core/target/classes/templates/dao", canonicalBasePath="/Users/rahulverma/git/by-rahul/one-click-code/template-services-code-core/target/classes/templates/dao/"), loader3 = FileTemplateLoader(baseDir="/Users/rahulverma/git/by-rahul/one-click-code/template-services-code-core/target/classes/templates/pom", canonicalBasePath="/Users/rahulverma/git/by-rahul/one-click-code/template-services-code-core/target/classes/templates/pom/"), loader4 = FileTemplateLoader(baseDir="/Users/rahulverma/git/by-rahul/one-click-code/template-services-code-core/target/classes/common", canonicalBasePath="/Users/rahulverma/git/by-rahul/one-click-code/template-services-code-core/target/classes/common/"), loader5 = ClassTemplateLoader(resourceLoaderClass=org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer, basePackagePath="" /* relatively to resourceLoaderClass pkg */)).
了解有关如何解决此问题的任何想法吗?
编辑:
我有这个最终的多模块项目(青色线),其中我收集每个模块的模板路径作为bean(粉红色线),最后将其注入配置中。 (粉色线)
我期待在 EntityTemplate.ftl 中导入具有函数/宏的 function.ftl 模板。 (黄线)请注意,function.ftl 与 EntityTemplate.ftl 完全位于不同的包中。我可以在 freeMarker 中实现此功能吗?我可以在其他模块中导入常用功能吗? 如果是的话我怎样才能实现这个目标?我尝试在类路径中提供模板 /common ,以便模板引擎可以搜索它,但它不能搜索并抛出模板未找到异常。关于如何实现这一目标有什么想法吗?目前我必须将functions.ftl 添加到每个目录,因为它只能在本地发现.ftl 文件。
使用
"classpath:/templates", "classpath:/templates/dao/", "classpath:/templates/pom/", "classpath:/common/"
,您可以指定模板 root 目录。这就是所有文件inside“dao”将出现在 FreeMarker 模板看到的顶层。
所以你应该简单地拥有
"classpath:/templates"
,然后将 commons
放入其中。当然,您也可以将 commons
放在其他地方,但是您必须在模板加载器路径中给出其父目录。
提示:您可以使用
${current_template_name}
了解当前模板名称(路径)是什么。