Freemarker - 迭代嵌套映射和嵌套列表

时间:2016-06-13 17:43:24

标签: java freemarker template-engine

我必须遍历List<Map<String, List<Map<String, String>>>>并打印其所有内容。

我的问题是,每次在嵌套级别使用map的括号语法(like in the documentation)时,我都会遇到语法问题。你能告诉我如何处理像List<Map<String, List<Map<String, String>>>>这样的类型的嵌套级别吗?

我测试了这个:

<!-- List<Map<String, List<Map<String, String>>>> -->
<#list myList as map1>

    <!-- Map<String, List<Map<String, String>>> -->
    <#list map1?keys as key1>
        My Key: ${key1}

        <!-- List<Map<String, String>> -->
        <#list map1[key1] as map2>


            <!-- Map<String, String> -->
            <#list map2?keys as key2>
                My Key: ${key2} | My Value: ${map2[key2]}
            </#list>
        </#list>
    </#list>
</#list>

我有这个错误:

java.lang.RuntimeException: freemarker.core.InvalidReferenceException: The following has evaluated to null or missing:
==> map1[key1]  [in template "hello.html" at line 39, column 32]

----
Tip: It's the final [] step that caused this error, not those before it.
----
Tip: If the failing expression is known to be legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----

----
FTL stack trace ("~" means nesting-related):
    - Failed at: #list map1[key1] as map2  [in template "hello.html" at line 39, column 25]
----

我正在使用Freemarker 2.3.23。感谢。

1 个答案:

答案 0 :(得分:0)

虽然是一个老问题,但作为标题分享答案非常通用,用户可以经常在这里寻找解决方案。请注意,输入为Map,即使我们的焦点数据类型为List,带有数据的列表也会添加到地图中,其中键myList与上面提到的相同模板。这符合下面引用的图书馆要求 -

  

通常,您希望使用Map或JavaBean作为根映射(也称为数据模型)参数。 Map key-s或JavaBean属性名称将是模板中的变量名称。

    public static void main(String[] args) {
        Map<String, Object> input = new HashMap<String, Object>();
        List<Map<String, List<Map<String, String>>>> l1 = new ArrayList<>();
        Map<String, List<Map<String, String>>> m1 = new HashMap<>();
        List<Map<String, String>> l2 = new ArrayList<Map<String,String>>();
        Map<String, String> m2 = new HashMap<String, String>();

        m2.put("m2", "m2v");
        l2.add(m2);
        m1.put("m1", l2);
        l1.add(m1);
        input.put("myList", l1);

        System.out.println(l1);

        Configuration cfg = new Configuration();
        try{
            FileTemplateLoader ftl = new FileTemplateLoader(new File("C:\\temp"));
            cfg.setTemplateLoader(ftl);
            Template temp = cfg.getTemplate("aa.ftlh");
            temp.process(input, new OutputStreamWriter(System.out));
        }catch(Exception e){
            e.printStackTrace();
        }
    }