Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从HashMap中检索列表对象并在自由标记模板中迭代?_Java_Freemarker - Fatal编程技术网

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

我有一个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[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)
是更干净的解决方案,但请参阅此答案中的更多内容: