将 java.lang.Iterable 视为 Freemarker 中的 #list 表达式

Posted

技术标签:

【中文标题】将 java.lang.Iterable 视为 Freemarker 中的 #list 表达式【英文标题】:Treat a java.lang.Iterable as a #list expression in Freemarker 【发布时间】:2011-09-05 16:03:55 【问题描述】:

我有一个 java.lang.Iterable(实际上是一个 com.google.gson.JsonArray 实例)。

我想使用 freemarker (2.3.16) 枚举列表中的项目。

[#assign sports = controller.sports]
[#-- At this point, sports is bound to a com.google.gson.JsonArray instance. --]

[#list sports as sport]
  $sport_index
[/#list]

我想避免仅仅为了有一个明确的项目集合而编写一个自定义 bean 和 Gson 反序列化器。使用 Gson(它已经为我将 JSON 字符串反序列化为 JsonObject)然后从该 JsonObject 创建我自己的对象 DAG 对我来说似乎很浪费。

不幸的是,我还没有找到让 Freemarker 将 java.lang.Iterable 视为列表的方法。我明白了:

freemarker.template.TemplateException : Expected collection or sequence.
  controller.sports evaluated instead to freemarker.ext.beans.XMLStringModel on line 8, column 16 in sports.html.
freemarker.core.TemplateObject.invalidTypeException(line:135)
freemarker.core.IteratorBlock$Context.runLoop(line:190)
freemarker.core.Environment.visit(line:417)
freemarker.core.IteratorBlock.accept(line:102)
freemarker.core.Environment.visit(line:210)

【问题讨论】:

【参考方案1】:

显式循环迭代器应该可以工作,例如:

[#list sports.iterator() as sport]
   $sport_index
[/#list]

【讨论】:

我觉得自从这篇文章以来有一个更好的解决方案,我实际上使用它......但似乎无法找到它并弄清楚所以我再次使用它!谢谢!【参考方案2】:

您所要做的就是将您的JsonArray 上的iterator() 的结果添加到上下文中。 Freemarker 足够聪明,可以从那里处理它,您可以像处理任何其他类似列表的变量一样在模板中引用它。

【讨论】:

【参考方案3】:

Freemarker 现在通过以下方式创建您的 freemarker 配置来支持 Iterable

configuration = new Configuration(VERSION_2_3_28);
DefaultObjectWrapper objectWrapper = new DefaultObjectWrapper(VERSION_2_3_28);
objectWrapper.setIterableSupport(true);
configuration.setObjectWrapper(objectWrapper);

并更新到 2.3.28 版本(我不确定是哪个版本添加了这个,但 .23 没有它),然后只需实例化您的 Template 并传入该配置。

return new Template("somename", someReader, configuration);

【讨论】:

以上是关于将 java.lang.Iterable 视为 Freemarker 中的 #list 表达式的主要内容,如果未能解决你的问题,请参考以下文章

错误:只能遍历数组或 java.lang.Iterable 的实例

for-each不适用于表达式类型必需的数组或java.lang.iterable

Java rt 包

Iterable 接口是不是有关于多次使用的官方合同?

java-集合框架4---foreach使用--for的增强使用

为什么数组没有实现Iterable接口,但可以使用foreach语句遍历