Freemarker - 带有Iterables的内置函数的行为

时间:2016-05-24 08:09:37

标签: size freemarker iterable

我正在观察Freemarker的奇怪行为。 我在Iterable中有一个reportModel.affectedJars。它由图形数据库提供 - Tinkerpop / Titan。

${iterableHasContent(reportModel.affectedJars)?then("true", "false")}<br>
${reportModel.affectedJars?has_content?then("yes", "no")} has_content<br>
${reportModel.affectedJars?size}<br>
${reportModel.affectedJars}<br>
<#if reportModel.affectedJars?size == 0>
    <p>No archives containing CVE vulnerabilities were found.</p>
<#else>
    <#list reportModel.affectedJars.iterator() as file>
        Something...

iterableHasContent?size的替代方案。 我希望这在以下方面非常一致:

false
no has_content
0
<p>No archives ...

但实际发生的是:

false
yes has_content
6
--- and no iterations. ---

看起来有些小问题让Freemarker认为Iterable不是空的,但是当迭代时,它没有提供任何项目。没有例外。

我正在尝试调试,但调试器由于某种原因没有停在相关代码处。

我在?size?has_content范例中缺少什么允许这种行为?

1 个答案:

答案 0 :(得分:1)

请勿尝试对Iterable执行任何操作,只需在其上调用iterator()即可。问题是FreeMarker是在Iterable被引入之前创建的,它看到一个纯Iterable(即,一个也没有实现Collection)作为通用对象,而不是一些可列出的东西。 (在不破坏向后兼容性的情况下修复此问题是不可能的,但肯定应该有一个配置选项。)这也是6的大小来源;它是散列中的项目数,包含其方法和JavaBean属性。啊...

所以在你得到Itera*tor*后,接下来你会发现它不支持?size。它支持?has_content。 (这假设您使用的是默认的对象包装器,而不是纯粹的BeansWrapper,这是纯粹的邪恶。)但是,如果可以,请使用嵌套#list的{​​{1}}。类似的东西:

#else

或更现实的例子:

<#list reportModel.affectedJars.iterator() as file>
    Something...
<#else>
    <p>No archives containing CVE vulnerabilities were found.</p>
</#list>