我有一个 Java Hashmap对象,它以org.w3c.dom.Element的形式存储一个键值对:java.util.ArrayList.在填充HashMap之后,我将它与org.w3c.dom.Element的List一起放在Freemarker上下文中. 当我尝试使用下面的代码片
当我尝试使用下面的代码片段获取List对象时
<#list ElementList as key> <#assign fh =ElemmentListMap> ${fh[key]} </#list>
它说${fh [key]}未定义.请让我如何获得解决方案或随意提供另一种解决方案.
更新:从2.3.22开始,您应该使用?api来解决这个问题.有关详细信息,请参见 this answer或 this FAQ entry.旧答案:
这里问题的根源是FreeMarker模板语言没有Java的Map类型的等价物.相反,它有一个名为“hash”的类型,类似于Map,但它只支持字符串键(最初是变量名).所以当它看到fh [key]时,它会假设key有一个字符串值(在这种情况下,由于POJO-s的包装方式,这将是key.toString()的结果),因此无法找到该项.因此,解决方案不是将[]运算符用于非字符串键,而是使用Java API,Map.get(Object键).
其余的已经过时了……
但是如果你尝试这样做,你将遇到另一个障碍:默认的ObjectWrapper不公开Map-s的方法,因为Map的字符串键已经填充了相同的名称空间.由于其他各种原因,我讨厌默认的ObjectWrapper,所以我总是像这样设置FreeMarker:
BeansWrapper wrapper = new BeansWrapper(); wrapper.setSimpleMapWrapper(true); cfg.setObjectWrapper(wrapper);
使用此包装器,您可以将Map-s用作myMap [someStringKey]或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,那么最后要考虑的事情.在这种情况下,你最好尝试以某种方式扩展…