代码之家  ›  专栏  ›  技术社区  ›  Nespony

在Scala中将Json对象解析为case类?

  •  0
  • Nespony  · 技术社区  · 6 年前

    第一个是这样的:

    {
                "uuid": "321,
                "uuidType": "series",
                "title": "a movie",
                "segments": [
                    "movie"
                ],
                "seriesIds": [
                    "123"
                ]
            }
    

    第二个是这样的:

     {
                "uuid": "1234",
                "uuidType": "programme",
                "title": "programme title",
                "type": "movie",
                "segments": [
                    "movies"
                ],
                "programmeIds": [
                    "321"
                ]
            }
    

    case class SearchResult(uuid: String, uuidType: String, title: String, segments: List[String], ids: List[String])
    

    因此,对于第二类对象,类型键和值将被忽略,第一个对象的seriesIds和第二个对象的programmeIds都将进入case类的ids部分。但是我不知道怎么做!我正在使用Circe解码/编码json。

    2 回复  |  直到 6 年前
        1
  •  1
  •   Sebastian Celestino    6 年前

    您可以在SearchResult对象伙伴中放置自定义解码器

    斯卡拉2.12

    import io.circe._
    import io.circe.parser._
    
    object Main extends App {
    
      val jsonA =
        """{
             "uuid": "321",
             "uuidType": "series",
             "title": "a movie",
             "segments": [
                "movie"
             ],
             "seriesIds": [
                "123"
             ]
           }"""
    
      val jsonB =
        """{
            "uuid": "1234",
            "uuidType": "programme",
            "title": "programme title",
            "type": "movie",
            "segments": [
              "movies"
            ],
            "programmeIds": [
              "321"
            ]
           }"""
    
      case class SearchResult(uuid: String, uuidType: String, title: String, segments: List[String], ids: List[String])
    
       object SearchResult {
    
        implicit val decoder: Decoder[SearchResult] = Decoder.instance { h =>
    
        for {
          uuid <- h.get[String]("uuid")
          uuidType <- h.get[String]("uuidType")
          title <- h.get[String]("title")
          segments <- h.get[List[String]]("segments")
          ids <- {
            h.getOrElse[List[String]]("seriesIds")(h.get[List[String]]("programmeIds").getOrElse(Nil))
          }
        } yield SearchResult(uuid, uuidType, title, segments, ids)
    
       }
    
      }
    
      val obj1 = decode[SearchResult](jsonA)
      println(obj1)
    
      val obj2 = decode[SearchResult](jsonB)
      println(obj2)
    
      }
    
        2
  •  2
  •   Arnon Rotem-Gal-Oz    6 年前

    您可以在circe中编写自定义代码以获得所需的效果,但在我看来,使用circe自动反序列化并将case类定义为

    case class SearchResult(uuid: String, uuidType: String, title: String, segments: List[String], programmeIds: Option[List[String]], seriesIds: Option[List[String]])
    

    并使用简单的scala代码将其转换为ids