Freemarker.template.TemplateException:预期的集合或序列

时间:2016-01-23 16:29:44

标签: json freemarker

我正在尝试在freemarker html模板中打印json数据。但要低于例外:

  

freemarker.template.TemplateException:预期的集合或   序列。 results.completedJobs评估为   freemarker.ext.beans.StringModel在第23行,第8列中   JobTrackingTemplate.ftl。在   freemarker.core.TemplateObject.invalidTypeException(TemplateObject.java:136)

***********************************************************************
        import org.json.JSONObject;
    import freemarker.template.Configuration;
    import freemarker.template.Template;
    import freemarker.template.TemplateException;
    import freemarker.template.TemplateExceptionHandler;


            Configuration cfg = new Configuration();
            cfg.setDirectoryForTemplateLoading(new File(templatesFolder));
            cfg.setDefaultEncoding("UTF-8");
            cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);


            Template template = cfg.getTemplate("test.ftl");

                     Map<String, Object> model = new HashMap<>();



             String json="{\"completedJobs\":[{\"completedTime\":\"Sat Jan 23 13:17:30 IST 2016\"}]"
                    + ",\"PendingJobs\":[],\"failedJobs\":[]}";
             JSONObject jsonObject= new JSONObject(json);


            jsonObject.put("todaysdate", Calendar.getInstance().getTime().toString());
            System.out.println(jsonObject);
            model.put("results", jsonObject);


            Writer out = new OutputStreamWriter(System.out);
            template.process(model, out);
        test.ftl
        ***********

        <html>
<head>Tracking Data - ${results.todaysdate}</head>
<body>

<h1>Allocated</h1>

<table border=2>
<tr>
    <td><B>time</B></td>


</tr>

<#list results.completedJobs as key>
    ${key.completedTime}

</#list>
</table>


</body>
</html>

1 个答案:

答案 0 :(得分:1)

results.completedJobs会调用JSONObject.get("completedJobs"),因为FreeMarker知道get(key)约定。结果是JSONArray。但是,这并没有实现List或任何熟悉的东西,因此FreeMarker并不知道如何列出它。如果你扩展DefaultObjectWrapper(或者你正在使用的任何对象包装器)以便将JSONArray - s包装成TemplateSquenceModel - s,然后使用Configuration.setObjectWrapper(yourCustomObjectWrapper),那么你将能够列出它。或者,你可以这样做,但它不是很好:

<#assign completedJobs = results.completedJobs>
<#list 0 ..< completedJobs.length() as i>
  ${completedJobs.get(i).completedTime}
</#list>

但是,如果你使用旧的FreeMarker,它就不会知道..<。你应该升级(我从错误信息中看到它有点旧版本。)