【问题标题】:Parse JSON object into list of objects将 JSON 对象解析为对象列表
【发布时间】:2019-11-26 20:30:08
【问题描述】:

我正在尝试使用 circe 将 JSON 对象解码为对象列表。我只想使用JSON响应的一些字段来创建对象,所以我觉得我必须创建一个自定义解码器。

我要制作序列的类定义如下:

case class Review(Id: String, ProductId: String, Rating: Int)

我尝试像这样创建自定义解码器:

implicit val reviewDecoder: Decoder[Review] = Decoder.instance { c =>

  val resultsC = c.downField("Results")

  for {
    id <- resultsC.downArray.get[String]("Id")
    productId <- resultsC.downArray.get[String]("ProductId")
    rating <- resultsC.downArray.get[Int]("Rating")
  } yield Review(id, productId, rating)
}

reviewDecoder.decodeJson(json) 似乎只做第一个结果,而不是全部。

我有一个这样的 JSON 响应:

 {
   "Limit":2,
   "Offset":0,
   "TotalResults":31,
   "Locale":"en_US", 
   "Results":
   [
      {"Id":"14518388",
       "CID":"21a9436b",
       "ProductId":"Product11", 
       "AuthorId":"jcknwekjcnwjk",
       "Rating":3
      },
      {"Id":"14518035",
       "CID":"8d67b6f5",
       "ProductId":"Product11",
       "AuthorId":"fnkjwernfk",
       "Rating":3
      }
   ],
   "Includes":{},
   "HasErrors":false,
   "Errors":[]}

我希望能够使用 circe 来解析这个 JSON 对象来创建一个 Seq[Review],但我不知道怎么做。

****Edit** Luis 的回答确实回答了这个问题,但说我有一个更复杂的类,我想创建一个序列:

case class User(id: Int)

case class Review(user: User, ProductId: String, Rating: Int)

在这种情况下,我如何能够创建一系列评论?

【问题讨论】:

    标签: json scala circe


    【解决方案1】:

    我只会使用光标来获取 Array,然后使用通用解码器。

    以下代码在 ammonite 上进行了测试,其中 json 是包含您的示例输入的字符串。

    import $ivy.`io.circe::circe-core:0.11.1`
    import $ivy.`io.circe::circe-generic:0.11.1`
    import $ivy.`io.circe::circe-parser:0.11.1`
    
    import io.circe.{Decoder, Jsom}
    import io.circe.parser.parse
    
    final case class Review(Id: String, ProductId: String, Rating: Int)
    implicit val reviewDecoder: Decoder[Review] = io.circe.generic.semiauto.deriveDecoder
    
    parse(json).getOrElse(Json.Null).hcursor.downField("Results").as[List[Review]]
    // res: io.circe.Decoder.Result[List[Review]] = Right(List(Review("14518388", "Product11", 3), Review("14518035", "Product11", 3)))
    

    【讨论】:

    • 如果名称不一对一匹配怎么办?假设 JSON 响应有一个名为“productId”的值,我想将其映射到对象成员“pID”,有没有办法指定哪个字段应该映射到哪个字段?
    • 是的,你可以。查看Documentation,转到Custom key mappings via annotations 部分。 (它在底部).
    猜你喜欢
    • 1970-01-01
    • 2021-11-14
    • 1970-01-01
    • 2020-03-15
    • 1970-01-01
    • 2020-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多