Я использую Модуль Джексона Scala , чтобы попытаться сериализовать и десериализовать классы случаев Scala как JSON.
В частности, я пытаюсь сделать это с абстрактным классом, который имеетпараметр типа, но десериализация не работает.Вместо десериализации JSON в объект класса параметра типа Джексон десериализует его в Map
, поэтому я не могу прочитать свойства объекта.
Вот код:
import com.fasterxml.jackson.annotation.{JsonSubTypes, JsonTypeInfo}
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
object StackOverflowExample {
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "@type")
@JsonSubTypes(Array(
new JsonSubTypes.Type(value = classOf[ResultWrapperSuccess[_]]),
new JsonSubTypes.Type(value = classOf[ResultWrapperFailure[_]])
))
trait ResultWrapperInterface[T] {
protected def obj: T
}
case class ResultWrapperSuccess[T](result: T) extends ResultWrapperInterface[T] {
override protected def obj: T = result
}
case class ResultWrapperFailure[F](failure: F) extends ResultWrapperInterface[F] {
override protected def obj: F = failure
}
case class User(name: String, age: Option[Int])
def main(args: Array[String]): Unit = {
val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)
val user = User("John Smith", Some(39))
val serializedUser = mapper.writeValueAsString(user)
println(s"(1) serializedUser: $serializedUser")
val deserializedUser = mapper.readValue(serializedUser, classOf[User])
println(s"(2) deserializedUser: $deserializedUser")
println(s"(3) deserializedUser.name: ${deserializedUser.name}")
val wrapperSuccess = ResultWrapperSuccess[User](user)
val serializedSuccess = mapper.writeValueAsString(wrapperSuccess)
println(s"(4) serializedSuccess: $serializedSuccess")
val deserializedSuccess = mapper.readValue(serializedSuccess, classOf[ResultWrapperInterface[User]])
deserializedSuccess match {
case _: ResultWrapperFailure[_] =>
case success: ResultWrapperSuccess[User] =>
println(s"(5) success: $success")
println(s"(6) success.result: ${success.result}")
println(s"(7) success.result.name: ${success.result.name}")
}
}
}
Первая часть, когда мы сериализуем и десериализуем объект User
, работает просто отлично.Код прерывается на (7), когда он пытается получить доступ к success.result.name
, потому что success.result
является каким-то образом Map
вместо User
.
Вот вывод:
(1) serializedUser: {"name":"John Smith","age":39}
(2) deserializedUser: User(John Smith,Some(39))
(3) deserializedUser.name: John Smith
(4) serializedSuccess: {"@type":"StackOverflowExample$ResultWrapperSuccess","result":{"name":"John Smith","age":39}}
(5) success: ResultWrapperSuccess(Map(name -> John Smith, age -> 39))
(6) success.result: Map(name -> John Smith, age -> 39)
Exception in thread "main" java.lang.ClassCastException: scala.collection.immutable.Map$Map2 cannot be cast to StackOverflowExample$User
at StackOverflowExample$.main(StackOverflowExample.scala:55)
at StackOverflowExample.main(StackOverflowExample.scala)
Как видно из логов, сериализация, кажется, работает просто отлично.Что-то, что мне нужно изменить, чтобы заставить работать десериализацию?