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

Scala:遍历Map与对象数组构建JSON时处理非字符串类型

问题:Play Framework JSON库构建JSON时非字符串类型被转为字符串

在Scala中使用Play Framework的Json库遍历Map和对象数组构建JSON时,遇到Double、LocalDate等非字符串类型被强制转换为字符串的问题,导致生成的JSON不符合预期类型。

原示例代码

import play.api.libs.json._
import java.time.Instant
import scala.util.Random

val Name: Array[String] = Array("Tester1","Tester2","Tester3")
val Typeids: Array[String] = Array("00000000-0000-0000-0000-000000000302","00000000-0000-0000-0000-000000003272","00000000-0000-0000-0000-000000006272")
val values: Array[Any] = Array(1264.3, java.time.LocalDate.now, "For Testing")

val i = 0
val data1 = (i to 2)
  .map { r =>
    Json.toJson(Map(
      "Name" -> Json.toJson(s"${Name(r%Name.length)}"),
      "typeId" -> Json.toJson(s"${Random.shuffle(Typeids.toList).head}"),
      "value" -> Json.toJson(s"${values(r%values.length)}")))    
  }

val data2 = Json.toJson(data1)
println(data2)

当前生成的JSON结果

[{"Name":"Tester1","typeId":"00000000-0000-0000-0000-000000006272","value":"1264.3"},{"Name":"Tester2","typeId":"00000000-0000-0000-0000-000000000302","value":"2022-10-19"},{"Name":"Tester3","typeId":"00000000-0000-0000-0000-000000006272","value":"For Testing"}]

期望的JSON结果

[{"Name":"Tester1","typeId":"00000000-0000-0000-0000-000000006272","value":1264.3},{"Name":"Tester2","typeId":"00000000-0000-0000-0000-000000000302","value":"2022-10-19"},{"Name":"Tester3","typeId":"00000000-0000-0000-0000-000000006272","value":"For Testing"}]


问题原因

  1. 字符串插值强制转换:原代码中使用s"${values(r%values.length)}"将所有类型的值统一转为字符串,Json.toJson接收的参数都是字符串类型,因此生成的JSON值会带引号。
  2. LocalDate无默认JSON格式:Play Framework的Json库默认不支持java.time.LocalDate的序列化,需要自定义格式规则。

解决方法及修正代码

关键步骤

  • 移除字符串插值,保留值的原始类型
  • 为LocalDate自定义JSON序列化格式
  • 通过模式匹配处理Any类型的值,根据实际类型生成对应类型的JSON值

修正后的代码

import play.api.libs.json._
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import scala.util.Random

// 为LocalDate自定义JSON格式:序列化为ISO日期字符串
implicit val localDateFormat: Format[LocalDate] = Format(
  Reads.localDateReads(DateTimeFormatter.ISO_LOCAL_DATE),
  Writes.localDateWrites(DateTimeFormatter.ISO_LOCAL_DATE)
)

val names: Array[String] = Array("Tester1","Tester2","Tester3")
val typeIds: Array[String] = Array("00000000-0000-0000-0000-000000000302","00000000-0000-0000-0000-000000003272","00000000-0000-0000-0000-000000006272")
val values: Array[Any] = Array(1264.3, LocalDate.now, "For Testing")

val data1 = (0 to 2).map { r =>
  val currentValue = values(r % values.length)
  // 根据值的实际类型生成对应的JsValue
  val valueJson = currentValue match {
    case d: Double => Json.toJson(d)
    case ld: LocalDate => Json.toJson(ld)
    case s: String => Json.toJson(s)
    case other => Json.toJson(other.toString) // 兜底处理其他未匹配类型
  }

  Json.toJson(Map(
    "Name" -> Json.toJson(names(r % names.length)),
    "typeId" -> Json.toJson(Random.shuffle(typeIds.toList).head),
    "value" -> valueJson
  ))
}

val data2 = Json.toJson(data1)
println(data2)

修正后输出结果

[{"Name":"Tester1","typeId":"00000000-0000-0000-0000-000000006272","value":1264.3},{"Name":"Tester2","typeId":"00000000-0000-0000-0000-000000000302","value":"2022-10-19"},{"Name":"Tester3","typeId":"00000000-0000-0000-0000-000000006272","value":"For Testing"}]


内容的提问来源于stack exchange,提问作者RUDRA GANESH SUBBARAYULU

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 17:15:43