Java 如何从HashMap中检索列表对象并在自由标记模板中迭代?
我有一个Java Hashmap对象,它以Java 如何从HashMap中检索列表对象并在自由标记模板中迭代?,java,freemarker,Java,Freemarker,我有一个Java Hashmap对象,它以org.w3c.dom.Element的形式存储键值对:Java.util.ArrayList。填充HashMap后,我将其与org.w3c.dom.Element列表一起放在Freemarker上下文中 当我尝试使用下面的代码片段获取列表对象时 <#list ElementList as key> <#assign fh =ElemmentListMap> ${fh[key]} </#list> ${fh[k
org.w3c.dom.Element
的形式存储键值对:Java.util.ArrayList
。填充HashMap
后,我将其与org.w3c.dom.Element
列表一起放在Freemarker上下文中
当我尝试使用下面的代码片段获取列表对象时
<#list ElementList as key>
<#assign fh =ElemmentListMap>
${fh[key]}
</#list>
${fh[key]}
它说,
${fh[key]}
未定义。请告诉我如何获得它的解决方案,或者随意给出另一个解决方案。尝试引用它,就像${fh.get(key)}
更新:从2.3.22开始,您应该使用?api
来解决这个问题。有关详细信息,请参见或
旧答案:
这里问题的根源在于FreeMarker模板语言没有与Java的Map
类型等价的语言。相反,它有一个名为“hash”的类型,类似于映射
,但它只支持字符串键(最初是变量名)。因此,当它看到fh[key]
时,它将假定key
有一个字符串值(在这种情况下,这将是key.toString()
的结果,因为POJO-s是如何包装的),因此不会找到该项。因此,解决方案不是对非字符串键使用[]
操作符,而是使用Java API,Map.get(Object key)
其余的都过时了…
但是如果您尝试这样做,您将遇到另一个障碍:默认的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
更糟糕的是,我看到您在这里使用W3CDOM。上面的包装不会自动包装节点
-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);
}
}
}
最后一件事要考虑的是,你使用FrimaRKER的环境已经有了一个自定义的代码> ObjtWrrPrpter <代码>。在这种情况下,您最好尝试以某种方式扩展…
您的java代码应该是:Map map = new HashMap();
List list = new ArrayList();
list.add("red");
list.add("green");
list.add("blue");
map.put("array_list", list);
<#list array_list as i>
${i}
</#list>
而自由标记模板应为:
Map map = new HashMap();
List list = new ArrayList();
list.add("red");
list.add("green");
list.add("blue");
map.put("array_list", list);
<#list array_list as i>
${i}
</#list>
这是行不通的。它给出了
freemarker.core.InvalidReferenceException
它在大多数freemarker配置中不起作用。它在某些情况下工作(取决于object\u wrapper
设置),尽管使用这种设置是个坏主意fh?api.get(key)
是更干净的解决方案,但请参阅此答案中的更多内容: