我正在使用 Freemarker v 2.3.32 并尝试列出免费标记模板内地图的值。但我的单元测试失败并出现以下错误:
freemarker.core.NonStringOrTemplateOutputException:对于“${...}”内容:期望一个字符串或其他可自动转换为字符串(数字、日期或布尔值)或“模板输出”的内容,但这已计算为方法+序列(包装器:f.e.b.SimpleMethodModel): [信息] ==> v [在模板“test.ftl”第 22 行第 11 列]
这是我的代码:
测试.ftl:
<ul>
<#list params as k,v>
<li>${v}</li>
<#else>
<p>Empty map</p>
</#list>
</ul>
def sampleHtmlTemplateWithMap(): util.Map[String, Any] = {
val data = Map("param1" -> "artifact1",
"param2" -> "artifact2")
val root = new mutable.HashMap[String, Any];
root("params") = data
root.asJava
}
在单元测试中,我做了以下事情:
val out = new StringWriter
testTemplate.process(sampleHtmlTemplateWithMap, out)
我可以毫无问题地打印 Scala 数组元素、字符串元素等。但我似乎无法访问 FTL 中的 Map 值。有人可以告诉我我做错了什么吗?
当我执行以下操作时,我遇到了同样的错误。
<#list params?values as v>
<li>${v}</li>
<#else>
<p>Empty map</p>
</#list>
</ul>
然而,当我尝试按键时,我看到一大堆 Scala.collections 方法,这次没有错误!但这不是我想要的
<#list params?keys as k>
<li>${k}</li>
<#else>
<p>Empty map</p>
</#list>
</ul>
另请注意,如果我指定键,我可以在 FTL 中单独访问 Map 元素,即
${params["param1"]}
它又回来了
Some(artifact1)
当我这样做时,我可以看到整个地图被打印出来:
${params}
如
Map(param1 -> artifact1, param2 -> artifact2)
请注意,您尚未将内部
data
映射转换为 Java 映射:
val data = Map("param1" -> "artifact1",
"param2" -> "artifact2")
(您仅将
.asJava
应用于 root
地图)。也许这就是问题所在。
但是,除此之外,尝试将 Scala 代码与 FreeMarker 等以 Java 为中心的库结合起来,是解决此类问题的良方。您可以考虑使用 Twirl 而不是 Freemarker 来获得方便且类型安全的模板解决方案。