json - 在 Scala 中转换 JSON 对象的问题

标签 json scala parsing json4s

我正在尝试制作一个简单的类示例 序列化在 Scala 中使用 json4s 图书馆,但即使在互联网上广泛搜索之后,不幸的是我找不到任何可以解决我的问题的令人满意的样本。

基本上我有一个简单的类叫做 Person我想从 JSON 字符串中提取此类的一个实例。

case class Person(
    val name: String,
    val age: Int,
    val children: Option[List[Person]]
)

所以当我这样做时:
val jsonStr = "{\"name\":\"Socrates\", \"age\": 70}"
println(Serialization.read[Person](jsonStr))

我得到这个输出:
"Person(Socrates,70,None)" // works fine!

但是当我在 JSON 字符串中没有年龄参数时,我收到此错误:

Exception in thread "main" org.json4s.package$MappingException: No usable value for age



我知道Person class 在其构造函数中有两个必需的参数,但我想知道是否有办法通过解析器或类似的东西进行这种转换。

另外,我试图制作这个解析器,但没有成功。

在此先感谢您的帮助。

最佳答案

假设您不想通过将其类型设置为 Option 来使年龄可选,然后您可以通过扩展 CustomSerializer[Person] 来编写自定义序列化程序.自定义序列化程序采用来自 Formats 的函数到 PartialFunction[JValue, Person] 的元组(您的 Person 解串器)和 PartialFunction[Any, JValue] (您的序列化程序)。

假设 Person.DefaultAge如果未给出年龄,则是您要为年龄设置的默认值,则自定义序列化程序可能如下所示:

object PersonSerializer extends CustomSerializer[Person](formats => ( {
  case JObject(JField("name", JString(name)) :: JField("age", JInt(age)) :: Nil) => Person(name, age.toInt, None)
  case JObject(JField("name", JString(name)) :: JField("age", JInt(age)) :: JField("children", JArray(children)) :: Nil) => Person(name, age.toInt, Some(children map (child => formats.customDeserializer(formats).apply(TypeInfo(classOf[Person], None), child).asInstanceOf[Person])))
  case JObject(JField("name", JString(name)) :: Nil) => Person(name, Person.DefaultAge, None)
  case JObject(JField("name", JString(name)) :: JField("children", JArray(children)) :: Nil) => Person(name, Person.DefaultAge, Some(children map (child => formats.customDeserializer(formats).apply(TypeInfo(classOf[Person], None), child).asInstanceOf[Person])))
}, {
  case Person(name, age, None) => JObject(JField("name", JString(name)) :: JField("age", JInt(age)) :: Nil)
  case Person(name, age, Some(children)) => JObject(JField("name", JString(name)) :: JField("age", JInt(age)) :: JField("children", formats.customSerializer(formats).apply(children)) :: Nil)
}))

这可能可以简化,因为有很多重复。此外,可能有更好的方法来递归调用序列化/反序列化。

关于json - 在 Scala 中转换 JSON 对象的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30407855/

相关文章:

scala - 如何使用精炼来表达常量 > 22 的约束

html - Play 框架中如何使用 IF 语句让 CSS 仅用于一页

php - 有没有比这更好的解析Youtube API XML的方法了?

c# - 如何在自定义声明(来自 Auth0)中反序列化 JSON?

json - 使用带有字典数组的字典解析 Swift JSON

arrays - 使用 jq 根据对象中的键值从数组返回整个对象

scala - scala编译出错,为什么是: val num =123;println(num. getClass())

html - 不插入 HTML 全局结构(如 &lt;!DOCTYPE>、<body>)的 HTML 命令行整洁

C#:如何只返回字符串中的第一组大写字母单词?

json - Visual Studio Code (Ruby) 未捕获的异常 - 无法加载此类文件