在 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。
任何帮助都是有用的
谢谢!
您可以为 Facts
和 AnimalType
定义 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))
// ))
// ))
我有一个非常复杂的 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。
任何帮助都是有用的
谢谢!
您可以为 Facts
和 AnimalType
定义 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))
// ))
// ))