91

Freemarker 有两种集合数据类型,lists 和 hashmaps 有没有办法像我们对 list 一样迭代 hashmap 键?

因此,如果我有一个带有数据的 var,可以说:

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

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

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

7 回答 7

114

编辑:不要将此解决方案与 FreeMarker 2.3.25 及更高版本一起使用,尤其是.get(prop). 查看其他答案。

您使用内置功能,例如这应该工作:

<#list user?keys as prop>
    ${prop} = ${user.get(prop)}
</#list>  
于 2009-09-30T12:27:19.847 回答
53

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

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>
于 2011-03-30T17:24:00.037 回答
52

从 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条目混合在一起。但是,如果您遇到这种不幸的设置,摆脱这种情况的方法是使用暴露的 Java 方法,例如user.entrySet(),user.get(key)等,而不是使用模板语言结构,例如?keysor user[key]

于 2016-07-08T17:25:29.813 回答
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 中,使用了 BeanWrapper 的扩展,默认的暴露级别允许这种迭代方式。

于 2012-05-07T14:48:54.950 回答
2

迭代对象

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

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

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

2)在Freemarker模板中迭代map,访问Key中的object和Value中的Object:

<#list convertedMap as item>
    <#assign myObjectKey = item.getKey()/>
    <#assign myObjectValue = item.getValue()/>
    [...]
</#list>
于 2015-06-20T08:42:08.450 回答
1

为了完整起见,值得一提的是,从最近开始,Freemarker 中的空集合处理得很好。

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

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

没有更多的<#if ...>包装。

于 2018-07-23T16:09:56.423 回答
0

您可以使用单引号来访问您在 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['firstname']}
${hash['lastname']}

输出 :

a
b
于 2015-03-19T18:28:55.113 回答