Apache Velocity vm模板转FreeMarker ftl模板的变量声明与类导入问题
Velocity转FreeMarker对应问题解决方案
静态工具类导入方案
FreeMarker没有模板内自动导入类的机制,工具类可通过两种方式暴露给模板调用:
- 全局配置(推荐,一次配置所有模板可用)
在Java层初始化FreeMarker的Configuration对象时,将工具类添加为共享变量:// 工具类为实例方法的场景 cfg.setSharedVariable("Utils", new com.utils.Utils()); // 工具类全为静态方法的场景 BeansWrapper wrapper = new BeansWrapperBuilder(Configuration.VERSION_2_3_31).build(); TemplateModel utilsStaticModel = wrapper.getStaticModels().get("com.utils.Utils"); cfg.setSharedVariable("Utils", utilsStaticModel); - 模板内临时引入
如果只需单个模板使用,可直接在模板内通过statics内置对象获取:
注意使用该方式需提前配置<#assign Utils = statics['com.utils.Utils']>BeansWrapper的访问权限,设置setExposureLevel(BeansWrapper.EXPOSE_ALL)即可。
User对象无法访问排查方案
已经能读取到包含user的Map但无法访问对象属性,基本为以下两个原因:
- 属性无符合JavaBean规范的公共getter:FreeMarker默认只能调用
public修饰的get方法访问属性,例如user.userName对应public String getUserName(),如果没有对应getter会报错。
解决方案:要么给对应属性添加公共get方法,要么修改对象包装器配置允许直接访问字段:BeansWrapper wrapper = new BeansWrapperBuilder(Configuration.VERSION_2_3_31) .setExposeFields(true) .setExposureLevel(BeansWrapper.EXPOSE_ALL) .build(); cfg.setObjectWrapper(wrapper); - 变量名大小写不匹配:FreeMarker大小写敏感,需确认Map中存储的user键名和模板中调用的名称完全一致,注意区分
user和User。
可选:IDE类型提示声明
如果需要和原Velocity的@vtlvariable注解一样实现IDE代码补全,可使用FreeMarker对应的文档注释:
<#-- @ftlvariable name="Utils" type="com.utils.Utils" --> <#-- @ftlvariable name="user" type="com.objects.UserObject" -->
该注释仅用于IDE静态提示,不影响模板运行逻辑。
内容的提问来源于stack exchange,提问作者Guy Cohen
相关产品推荐
相关产品推荐

