"1", "id"-6ren">
gpt4 book ai didi

json - 为什么我不能将 Map[String,Any] 序列化为 JSON?

转载 作者:行者123 更新时间:2023-12-01 06:18:22 29 4
gpt4 key购买 nike

当它具有不同类型的值时,我似乎无法找到将我的 Map 序列化为 JSON 对象的正确方法,即:

var user: Map[String, Any] = Map("name" -> "1", "id" -> 1)
val json: JsValue = Json.obj(
"user" -> user
)

产生:

type mismatch;
found : Map[String,Any]
required: play.api.libs.json.Json.JsValueWrapper

或者,如果我改用 Map[String,AnyVal],它会产生:

the result type of an implicit conversion must be more specific than AnyVal

但是如果我使用 Map[String,Number]Map[String,String] 它就可以了。

我缺少什么,是否有一些包装器可以调用以在我的 JSON.obj() 调用中安全地使用数字和整数?

最佳答案

根据您的代码片段,您需要执行以下操作:

var user = Map("name" -> "1", "id" -> 1)
var json: JsValue = Json.obj(
"user" -> Json.toJson(user)
)

下一个会出现的问题是 Play 找不到类型 Map[String, Any] 的隐式 writes

我建议为您尝试序列化的对象编写您自己的Writes。也许像下面这样:

case class User(props: Map[String, Any])

implicit val writes: Writes[User] = new Writes[User]{
override def writes(o: User): JsValue = {
val propsJs = JsObject(
o.props.map{kvp =>
kvp._1 -> (kvp._2 match {
case x: String => JsString(x)
case x: Int => JsNumber(x)
case _ => JsNull // Do whatever you want here.
})
}
)
JsObject(Map("user" -> propsJs))
}
}

通过测试:

val u1 = User(Map("name" -> "1", "id" -> 1))

val js = Json.toJson(u1)

out: js: play.api.libs.json.JsValue = {"user":{"name":"1","id":1}}

编辑:

正如评论中所指出的,执行以下操作可能会有好处(取决于您的用例):

case class User(name: String, id: Int)

implicit val writes = Json.writes[User]

这是一个更具可读性并且更好地巩固了User的定义。您可能无法这样做,但如果可以的话,我(和其他人)会建议这样做。

关于json - 为什么我不能将 Map[String,Any] 序列化为 JSON?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36981111/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com