Freemarker:在哈希中迭代嵌套列表

时间:2014-12-03 05:52:31

标签: java java-ee freemarker

我想迭代嵌套在Map中的List,数据结构如下:

Map<Integer, List<Integer>> groups = new TreeMap<>()
// Some code else to put values into groups ...

Freemarker模板:

<#list groups?keys as groupKey>
    ${groupKey}    // It's OK here.
    <#list groups[groupKey] as item>  // Exception threw here, detail message is pasted below
        ${item}
    </#list>
</#list>

详细信息异常消息:

  

FreeMarker模板错误:   对于“...... [...]”左手操作数:期望一个序列或字符串或某些东西可自动转换为字符串(数字,日期或布尔值),但这被评估为extended_hash(包装器:f.t.SimpleHash):   ==&GT;组

那么,问题是什么?

P.S。

我尝试了groups.get(groupKey)而不是groups[groupKey],它会抛出一个新的异常堆栈:

java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
java.lang.String.compareTo(String.java:108)
java.util.TreeMap.getEntry(TreeMap.java:346)
java.util.TreeMap.get(TreeMap.java:273)
freemarker.template.SimpleHash.get(SimpleHash.java:160)
freemarker.core.Dot._eval(Dot.java:40)
freemarker.core.Expression.eval(Expression.java:76)

2 个答案:

答案 0 :(得分:6)

原始问题中的问题是FTL的哈希类型与Map不同。它是“变量”的集合,即密钥必须是String - s。 (即使?keys起作用也是BeansWrapper中的一个小问题...虽然它现在很方便。)由于键是一个数字,FTL假定你想从序列中获取一个项目(a { {1}}或数组),或者您想从字符串中获取字符,因此是原始错误消息。

解决方案是使用Java API-s,例如Dev-an的答案中的List。 (在长期FTL意味着引入地图类型,因此所有这些非字符串键的问题都将结束,但是谁知道这将是什么时候......)

更新:从2.3.22起,get可以访问对象的Java API,例如?api。但是,默认情况下不允许(请参阅手册中的myMap?api.get(nonStringKey)配置设置和更多内容:http://freemarker.org/docs/ref_builtins_expert.html#ref_buitin_api_and_has_api)。另请注意,由于Java映射与数字类型有关,如果密钥不是来自Java的api_builtin_enabled,则必须使用Integer

答案 1 :(得分:1)

尝试以下方法:

<#list groups?keys as groupKey>
    ${groupKey}
    <#list groups.get(groupKey) as item>
        ${item}
    </#list>
</#list>