4

org.w3c.dom.Element我有一个 Java Hashmap 对象,它以:的形式存储键值对java.util.ArrayList。填充后HashMap,我将它与 List of 一起放入 Freemarker 上下文中org.w3c.dom.Element

当我尝试使用下面的代码片段获取 List 对象时

<#list ElementList as key>
<#assign fh =ElemmentListMap>
  ${fh[key]}
</#list>

它说${fh[key]}是未定义的。请让我如何获得解决方案或随时提供其他解决方案。

4

2 回答 2

4

更新:从 2.3.22 开始,您应该只使用?api来解决这个问题。有关详细信息,请参阅此答案此常见问题解答条目

旧答案:

问题的根源在于 FreeMarker 模板语言没有MapJava 类型的等价物。相反,它有一种称为“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. 在这种情况下,你最好尝试以某种方式扩展它......

于 2012-04-14T14:46:50.093 回答
0

你的java代码应该是:

Map map = new HashMap();
List list = new ArrayList();
list.add("red");
list.add("green");
list.add("blue");
map.put("array_list", list);

freemarker 模板应该是:

<#list array_list as i>
    ${i}
</#list>

输出

red
green
blue 
于 2013-11-01T15:56:45.623 回答