【发布时间】:2019-09-07 05:36:27
【问题描述】:
设置
我正在使用 json4s 3.2.11 和 Scala 2.11。
我有一个使用sealed trait 定义的枚举和一个自定义序列化程序:
import org.json4s.CustomSerializer
import org.json4s.JsonAST.JString
import org.json4s.DefaultFormats
import org.json4s.jackson.Serialization
sealed trait Foo
case object X extends Foo
case object Y extends Foo
object FooSerializer
extends CustomSerializer[Foo](
_ =>
({
case JString("x") => X
case JString("y") => Y
}, {
case X => JString("x")
case Y => JString("y")
})
)
这很棒,添加到格式时效果很好:
{
implicit val formats = DefaultFormats + FooSerializer
Serialization.write(X) // "x"
}
这太棒了!
问题
如果格式中没有添加序列化器,json4s 会使用反射来创建字段的默认表示,这对于这些没有字段的objects 非常无益。它默默地执行此操作,似乎无法控制它。
{
implicit val formats = DefaultFormats
Serialization.write(X) // {}
}
这是一个问题,因为直到很久以后才有迹象表明出了什么问题。如果测试没有碰巧捕捉到这些无效/无用数据,则可能会通过网络发送或写入数据库。而且,这可能会从图书馆公开暴露,这意味着下游用户也必须记住它。
注意。这与read 不同,后者在失败时抛出异常,因为Foo trait 没有任何有用的构造函数:
{
implicit val formats = DefaultFormats
Serialization.read[Foo]("\"x\"")
}
org.json4s.package$MappingException: No constructor for type Foo, JString(x)
at org.json4s.Extraction$ClassInstanceBuilder.org$json4s$Extraction$ClassInstanceBuilder$$constructor(Extraction.scala:417)
at org.json4s.Extraction$ClassInstanceBuilder.org$json4s$Extraction$ClassInstanceBuilder$$instantiate(Extraction.scala:468)
at org.json4s.Extraction$ClassInstanceBuilder$$anonfun$result$6.apply(Extraction.scala:515)
...
问题
有没有办法禁用这些对象的默认{} 格式,或者将格式“烘焙”到对象本身?
例如,让write 抛出类似read 的异常就可以了,因为它会立即将问题标记给调用者。
【问题讨论】:
标签: scala serialization reflection json4s