如何在scala中使用Circe解码JSON列表/数组 [英] How to Use Circe for Decoding JSON Lists/Arrays in Scala
问题描述
我有代码段
cursor.downField("params").downField("playlist").downField("items").as[List[Clip]]
其中Clip是字符串和数字的简单案例类.传入的Json应该包含一个带有项目"数组的json对象播放列表",其中每个项目都是一个剪辑.所以json应该看起来像
Where Clip is a simple case class of strings and numbers. The incoming Json should contain a json object "playlist" with an array of "items" where each item is a clip. So the json should look like
{
"playlist": {
"name": "Sample Playlist",
"items": [
{
"clipId":"xyz",
"name":"abc"
},
{
"clipId":"pqr",
"name":"def"
}
]
}
}
使用上面的代码段,我得到了编译错误:
With the code snippet above, I'm getting the compile error:
Error:(147, 81) could not find implicit value for parameter d:
io.circe.Decoder[List[com.packagename.model.Clip]]
cursor.downField("params").downField("playlist").downField("items").as[List[Clip]]
我做错了什么?您如何使用circe设置简单项目列表/数组的解码?
What am I doing wrong? How do you setup decoding for a list/array of simple items using circe?
推荐答案
为了完整起见,您可以创建一个自定义解码器,在处理过程中包括导航:
For the sake of completeness, instead of navigating into the JSON value and then decoding the clips, you could create a custom decoder that includes the navigation in its processing:
import io.circe.Decoder, io.circe.generic.auto._
case class Clip(clipId: String, name: String)
val decodeClipsParam = Decoder[List[Clip]].prepare(
_.downField("params").downField("playlist").downField("items")
)
然后,如果您有此提示:
And then if you've got this:
val json = """{ "params": {
"playlist": {
"name": "Sample Playlist",
"items": [
{
"clipId":"xyz",
"name":"abc"
},
{
"clipId":"pqr",
"name":"def"
}
]
}
}}"""
您可以像这样使用解码器:
You can use the decoder like this:
scala> io.circe.parser.decode(json)(decodeClipsParam)
res3: Either[io.circe.Error,List[Clip]] = Right(List(Clip(xyz,abc), Clip(pqr,def)))
我可能会更进一步,并使用自定义案例类:
I'd probably go a step further and use a custom case class:
import io.circe.generic.auto._
import io.circe.generic.semiauto.deriveDecoder
case class Clip(clipId: String, name: String)
case class PlaylistParam(name: String, items: List[Clip])
object PlaylistParam {
implicit val decodePlaylistParam: Decoder[PlaylistParam] =
deriveDecoder[PlaylistParam].prepare(
_.downField("params").downField("playlist")
)
}
现在您可以这样写:
scala> io.circe.parser.decode[PlaylistParam](json).foreach(println)
PlaylistParam(Sample Playlist,List(Clip(xyz,abc), Clip(pqr,def)))
不过,如何拆分导航和解码主要取决于口味.
How you want to split up the navigation and decoding is mostly a matter of taste, though.
这篇关于如何在scala中使用Circe解码JSON列表/数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!