You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 04:15:02