如何提取Freemarker模板中所有需要填充的变量列表?
Freemarker模板变量提取解决方案
优先方案:AST节点遍历(官方原生支持,准确率最高)
Freemarker解析模板时会生成完整的抽象语法树(AST),你可以直接通过遍历AST提取所有变量,完全不需要自行实现正则匹配,步骤如下:
- 统一收集所有模板内容:包括主模板原始内容,以及所有会通过
block.content?interpret执行的动态区块原始内容,无需等待运行时合成,直接分别解析即可 - 调用Freemarker的
Template类的构造方法,将每一份模板内容解析为AST结构 - 自定义继承
DefaultTemplateVisitor的访问器类,重写visit(DollarVariable)方法,遍历每个${}插值节点的表达式,提取所有自定义标识符,可以过滤掉index、has_next这类循环内置变量,以及data_model、env等Freemarker内置全局变量 - 对收集到的所有变量做去重处理,即可得到最终需要用户填充的完整变量列表
备选方案:缺失变量捕获
如果你的模板没有复杂的分支判断逻辑,可以用该方案快速实现:
- 构造一个空的DataModel,自定义
TemplateExceptionHandler,捕获所有MissingVariableException,提取异常中携带的变量名 - 执行一次模板渲染,过程中所有被访问到的缺失变量都会被收集
注意:该方案无法覆盖<#if>、<#switch>等分支中未触发路径下的变量,仅适合逻辑简单的模板使用
为什么不推荐正则匹配
正则无法处理复杂的Freemarker语法场景,比如嵌套插值${user.info?default("${fallbackVal}")}、带方法调用的表达式${getUser(id).name}、赋值语句中的变量引用等,很容易出现提取遗漏或者结果错误的问题。
内容的提问来源于stack exchange,提问作者M. Deinum
相关产品推荐
相关产品推荐

