反序列化Scala case类时,如何跳过Jackson中的包装JSON对象?
我有来自外部系统的以下格式的数据:反序列化Scala case类时,如何跳过Jackson中的包装JSON对象?,json,scala,jackson,Json,Scala,Jackson,我有来自外部系统的以下格式的数据: { "type": "text", "data": { "text": "Here's some text" } } type有许多值,在data中有不同的字段,所有值都有相应的case类,它们应该作为顶级结构的一部分反序列化到这些case类中,例如: case class TopLevel(parts: Part) sealed trait Part case class Text(text: String) extends Part
{
"type": "text",
"data": {
"text": "Here's some text"
}
}
type
有许多值,在data
中有不同的字段,所有值都有相应的case类,它们应该作为顶级结构的一部分反序列化到这些case类中,例如:
case class TopLevel(parts: Part)
sealed trait Part
case class Text(text: String) extends Part
case class Image(url: String, ...) extends Part
...
如果不在
Part
周围创建包装器,如何以一种好的方式完成这项工作?您需要为您的类型创建一个自定义序列化程序。大概是这样的:
import org.json4s.{CustomSerializer, DefaultFormats, Extraction, JObject, JString}
import org.json4s.jackson.JsonMethods.parse
import org.json4s.jackson.Serialization
class PartSerializer extends CustomSerializer[Part](format => ( {
case JObject(("type", JString(typeString)) :: ("data", obj) :: Nil) =>
implicit val f = format
typeString match {
case "text" =>
Extraction.extract[Text](obj)
case "image" =>
Extraction.extract[Image](obj)
}
}, {
case text: Text =>
implicit val f = format
JObject(List(
("type", JString("text")),
("data", JObject(List(
("text", JString(text.text))))
),
))
case img: Image =>
implicit val f = format
JObject(List(
("type", JString("image")),
("data", JObject(List(
("url", JString(img.url))))
),
))
}
))
implicit val formats = DefaultFormats + new PartSerializer()
// Parse JSON
val part = Extraction.extract[Part](parse(json))
// Generate JSON
val json = Serialization.write(part)
然后您可以这样使用它:
import org.json4s.{CustomSerializer, DefaultFormats, Extraction, JObject, JString}
import org.json4s.jackson.JsonMethods.parse
import org.json4s.jackson.Serialization
class PartSerializer extends CustomSerializer[Part](format => ( {
case JObject(("type", JString(typeString)) :: ("data", obj) :: Nil) =>
implicit val f = format
typeString match {
case "text" =>
Extraction.extract[Text](obj)
case "image" =>
Extraction.extract[Image](obj)
}
}, {
case text: Text =>
implicit val f = format
JObject(List(
("type", JString("text")),
("data", JObject(List(
("text", JString(text.text))))
),
))
case img: Image =>
implicit val f = format
JObject(List(
("type", JString("image")),
("data", JObject(List(
("url", JString(img.url))))
),
))
}
))
implicit val formats = DefaultFormats + new PartSerializer()
// Parse JSON
val part = Extraction.extract[Part](parse(json))
// Generate JSON
val json = Serialization.write(part)
如果
零件
数据嵌入到外部对象中,此功能也会起作用。谢谢!我如何将其用于对象映射器
?看起来您似乎调用了mapper.addSerializer(Part.class,new PartSerializer())
,但我没有使用对象映射器,因此这可能是错误的。哦,等等。我一定很累了。我的意思是反序列化,而不是序列化:/ACustomSerializer
同时执行序列化和反序列化,如我的示例所示。那么,addSerializer
是否仍能正常工作?正如我所说,我不使用对象映射器,所以我无法轻松测试。你能在部分添加注释吗?
?是的,模型的内部表示是我的