You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在FreeMarker模板中遍历Scala Map值失败的问题排查

FreeMarker遍历Scala Map值时抛出NonStringOrTemplateOutputException错误

错误信息

freemarker.core.NonStringOrTemplateOutputException: For "${...}" content: Expected a string or something automatically convertible to string (number, date or boolean), or "template output" , but this has evaluated to a method+sequence (wrapper: f.e.b.SimpleMethodModel):
[info] ==> v  [in template "test.ftl" at line 22, column 11]

相关代码

test.ftl模板代码

<ul>
<#list params as k,v>
    <li>${v}</li>
<#else>
   <p>Empty map</p>
</#list>
</ul>

Scala数据准备代码

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)

尝试过的操作及结果

  • 尝试遍历Map值(<#list params?values as v>),抛出相同错误
  • 遍历Map键(<#list params?keys as k>)时无报错,但输出大量Scala集合类的方法名,非预期的Map键
  • 单独通过键访问元素(${params["param1"]})可行,返回结果为Some(artifact1)
  • 直接打印整个Map(${params})正常,输出:Map(param1 -> artifact1, param2 -> artifact2)

问题原因及解决方案

问题根源

传入FreeMarker的params本质是Scala的Map实例,而非Java标准的java.util.Map。FreeMarker默认的对象包装器无法正确识别Scala集合的Map特性,导致遍历逻辑错误:将Map实例当成普通对象处理,遍历其方法/属性而非键值对,最终渲染值时将方法对象当成了要输出的内容,抛出类型转换异常。

解决方案

将Scala的Map显式转换为Java的java.util.Map,确保FreeMarker能正确识别为Map类型。修改Scala数据准备代码:

import scala.collection.JavaConverters._

def sampleHtmlTemplateWithMap(): util.Map[String, Any] = {
    val data = Map("param1" -> "artifact1",
      "param2" -> "artifact2")
    val root = new mutable.HashMap[String, Any]()
    // 将Scala Map转换为Java Map
    root("params") = data.asJava
    root.asJava
}

修改后,FreeMarker就能正确解析params为Map类型,<#list params as k,v>和<#list params?values as v>都能正常遍历并输出值,单独访问键也会直接返回字符串值而非Some(...)。


内容的提问来源于stack exchange,提问作者user1452348

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 10:26:00