在 Json4s 中将(非常)复杂的 JSON 对象转换为带有大小写 类 的 Scala 对象

Converting (Very) Complicated JSON objects to Scala Objects With Case Classes In Json4s

我有一个非常复杂的 JSON 文件,如下所示:

       {
            "Animals": [
                [
                    100,
                    "Mammals",
                    [
                        1,
                        "Cat",
                        50,
                        45,
                        57,
                        -1
                    ],
                    [
                        2,
                        "Dog",
                        31,
                        44,
                        18,
                        -1
                    ]
                ],
    [
                159,
                "Reptiles",
                [
                    1,
                    "Lizard",
                    11,
                    12,
                    9,
                    -1
                ]
            ]
]
    }

我正在尝试解析此结构并以某种方式从中获取 Scala 对象。

这是我的尝试:

case class Facts(number: Int, subTypeOfAnimal: String, data: List[Int])

case class Animaltype(value: Int, typeOfAnimal: String, characteristics: List[Facts])

case class Animal(rows: List[Animaltype])

这当然无法转换数据。它 returns 一个 JNothing。我想知道如何在这种 JArray 中正确地表达复杂的 JArray。

任何帮助都是有用的

谢谢!

您可以为 FactsAnimalType 定义 CustomSerializer

import scala.util.Try

import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.native.JsonMethods._
import org.json4s.native.Serialization

case class Facts(number: Int, subTypeOfAnimal: String, data: List[Int])
case class AnimalType(value: Int, typeOfAnimal: String, characteristics: List[Facts])
case class Animal(Animals: List[AnimalType])

implicit val formats = Serialization.formats(NoTypeHints) + 
  new AnimalTypeSerializer + new FactsSerializer

class FactsSerializer extends CustomSerializer[Facts](format => ( {
  case JArray(JInt(nr) :: JString(subType) :: data) => 
    Facts(nr.toInt, subType, data.collect{ case JInt(i) => i.toInt})
}, { case _ => throw new RuntimeException("No serializing")}))

class AnimalTypeSerializer extends CustomSerializer[AnimalType](format => ( {
  case JArray(JInt(value) :: JString(typeAnimal) :: factsArrays) => 
    val facts = factsArrays.collect { case facts: JArray => 
      Try(facts.extract[Facts]).toOption
    }.flatten
    AnimalType(value.toInt, typeAnimal, facts)
}, { case _ => throw new RuntimeException("No serializing")}))

如果您将输入 json 作为值 json,您可以使用 :

反序列化它
parse(json).extract[Animal]
// Animal = Animal(List(
//   AnimalType(100,Mammals,List(
//     Facts(1,Cat,List(50, 45, 57, -1)), Facts(2,Dog,List(31, 44, 18, -1))
//   )),
//   AnimalType(159,Reptiles,List(
//     Facts(1,Lizard,List(11, 12, 9, -1))
//   ))
// ))