更新:从 2.3.22 开始,您应该只使用?api
来解决这个问题。有关详细信息,请参阅此答案或此常见问题解答条目。
旧答案:
问题的根源在于 FreeMarker 模板语言没有Map
Java 类型的等价物。相反,它有一种称为“hash”的类型,类似于 a Map
,但它只支持字符串键(最初是变量名)。所以当它看到 时fh[key]
,它会假设key
有一个字符串值(在这种情况下,这将是key.toString()
由于 POJO 的包装方式的结果),因此不会找到该项目。所以解决方案不是使用[]
非字符串键的操作符,而是使用 Java API Map.get(Object key)
,.
其余的都过时了...
但是,如果您尝试这样做,您将遇到另一个障碍:默认ObjectWrapper
不公开Map
-s 的方法,因为Map
已经填充了相同的名称空间的字符串键。由于各种其他原因,我也讨厌默认ObjectWrapper
设置,所以我总是这样设置 FreeMarker:
BeansWrapper wrapper = new BeansWrapper();
wrapper.setSimpleMapWrapper(true);
cfg.setObjectWrapper(wrapper);
使用此包装器,您可以使用Map
-s asmyMap[someStringKey]
或 as myMap(whateverKey)
。所以在你的情况下它会是${fh(key)}
。同样,这不适用于默认的ObjectWrapper
.
更糟糕的是,我看到您在这里使用的是 W3C DOM。上面的包装器不会Node
以某种方式自动包装 -s 以便您可以使用 FreeMarker XML 功能。因此,如果您需要,除非您总是手动包装 DOM 节点,否则您将不得不扩展BeansWrapper
以识别 DOM 节点。幸运的是,这很简单:
public class MyObjectWrapper extends freemarker.ext.beans.BeansWrapper {
public TemplateModel wrap(Object obj) throws TemplateModelException {
if (obj instanceof org.w3c.dom.Node) {
return freemarker.ext.dom.NodeModel.wrap((org.w3c.dom.Node) obj);
} else {
return super.wrap(obj);
}
}
}
如果您使用 FreeMarker 的环境已经有一个自定义的ObjectWrapper
. 在这种情况下,你最好尝试以某种方式扩展它......