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

发布于 2024-11-11 14:51:48 字数 969 浏览 3 评论 0原文

我有一个 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)

I have a java.lang.Iterable (in fact, a com.google.gson.JsonArray instance).

I would like to enumerate the items in the list using 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]

I would like to avoid having to write a custom bean and Gson deserializer just to have an explicit collection of items. Using Gson (which already deserializes the JSON string to a JsonObject for me) to then create my own DAG of objects from that JsonObject seems wasteful to me.

Unfortunately, I haven't been able to work out a way of getting Freemarker to treat the java.lang.Iterable as a list. I get:

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

鲜血染红嫁衣 2024-11-18 14:51:48

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

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

Explicitly looping over the iterator should work, e.g.:

[#list sports.iterator() as sport]
   ${sport_index}
[/#list]
叫嚣ゝ 2024-11-18 14:51:48

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

All you have to do is add the result of iterator() on your JsonArray to the context. Freemarker is smart enough to handle it from there, and you can reference it in your template like you do any other list-like variable.

小清晰的声音 2024-11-18 14:51:48

Freemarker 现在支持 Iterable,通过以下方式创建 freemarker 配置:

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);

Freemarker now supports Iterable's by creating your freemarker config via:

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

and updating to the 2.3.28 release (I'm not exactly sure which version added this, but .23 didn't have it), then simply instantiate your Template passing in that configuration.

return new Template("somename", someReader, configuration);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文