Freemarker迭代hashmap键

时间:2009-09-30 12:22:02

标签: java freemarker

Freemarker有两种集合数据类型,列表和哈希映射 有没有办法迭代hashmap键,就像我们对列表一样?

所以,如果我有一个带数据的var,那就说:

user : {
  name : "user"
  email : "looser@everything.com"
  homepage : "http://nosuchpage.org"
}

我想用它们的值打印所有用户的属性。 这是无效的,但目标很明确:

<#list user.props() as prop>
  ${prop} = ${user.get(prop)}
</#list>

7 个答案:

答案 0 :(得分:99)

编辑:请勿在FreeMarker 2.3.25及更高版本中使用此解决方案,尤其不要使用.get(prop)。请参阅其他答案。

您使用内置的keys功能,例如这应该有效:

<#list user?keys as prop>
    ${prop} = ${user.get(prop)}
</#list>  

答案 1 :(得分:48)

仅供参考,看起来检索值的语法已根据以下内容进行了更改:

http://freemarker.sourceforge.net/docs/ref_builtins_hash.html

<#assign h = {"name":"mouse", "price":50}>
<#assign keys = h?keys>
<#list keys as key>${key} = ${h[key]}; </#list>

答案 2 :(得分:35)

从2.3.25开始,就像这样:

<#list user as propName, propValue>
  ${propName} = ${propValue}
</#list>

请注意,这也适用于非字符串键(与map[key]不同,后者必须写为map?api.get(key))。

在2.3.25之前,标准解决方案是:

<#list user?keys as prop>
  ${prop} = ${user[prop]}
</#list>

但是,一些非常古老的FreeMarker集成使用了一种奇怪的配置,其中公共Map方法(如getClass)显示为键。发生这种情况的原因是他们使用的是BeansWrapper DefaultObjectWrapper simpleMapWrapper false属性的纯Map。您应该避免这样的设置,因为它将方法与真实的user.entrySet()条目混合在一起。但是如果遇到这种不幸的设置,逃避这种情况的方法是使用公开的Java方法,例如user.get(key)?keys等,而不是使用像{{1这样的模板语言结构}或user[key]

答案 3 :(得分:12)

如果使用曝光级别为Expose.SAFE或Expose.ALL的BeansWrapper,则可以采用迭代条目集的标准Java方法:

例如,以下内容适用于Freemarker(至少从版本2.3.19开始):

<#list map.entrySet() as entry>  
  <input type="hidden" name="${entry.key}" value="${entry.value}" />
</#list>

例如,在Struts2中,an extension of the BeanWrapper与默认的曝光级别一起使用以允许这种迭代方式。

答案 4 :(得分:2)

迭代对象

如果你的地图键是一个对象而不是一个字符串,你可以使用Freemarker迭代它。

1)将地图转换为控制器中的列表:

List<Map.Entry<myObjectKey, myObjectValue>> convertedMap  = new ArrayList(originalMap.entrySet());

2)在Freemarker模板中迭代地图,访问Key中的对象和Value中的Object:

<#list convertedMap as item>
    <#assign myObjectKey = item.getKey()/>
    <#assign myObjectValue = item.getValue()/>
    [...]
</#list>

答案 5 :(得分:1)

您可以使用单引号访问您在Java程序中设置的密钥
如果你像这样用Java设置Map

Map<String,Object> hash = new HashMap<String,Object>();
hash.put("firstname", "a");
hash.put("lastname", "b");

Map<String,Object> map = new HashMap<String,Object>();
map.put("hash", hash);

然后你可以像这样访问Freemarker中'hash'的成员 -

${hash['firstname']}
${hash['lastname']}

输出:

a
b

答案 6 :(得分:0)

为完整起见,值得一提的是,自最近以来,Freemarker中对空集合进行了不错的处理。

所以迭代地图最方便的方法是:

<#list tags>
<ul class="posts">
    <#items as tagName, tagCount>
        <li>{$tagName} (${tagCount})</li>
    </#items>
</ul>
<#else>
    <p>No tags found.</p>
</#list>

不再有<#if ...>包装器。