FasterXML / FasterXML/jackson-module-scala
Cannot deserialize abstract class with type parameter
- Ngôn ngữ chính
- Scala
- Star
- 506
- Fork
- 138
- Merge trung bình
- 3 giờ 6 phút
- Pull request đã merge (30 ngày)
- 48
Mô tả
I'm trying to serialize and deserialize an abstract class that has a type parameter, but the deserialization isn't working. Instead of deserializing the JSON into an object of the type parameter's class, Jackson deserializes it into a `Map`, so I'm unable to read the object's properties.
Here is the code:
```scala
import com.fasterxml.jackson.annotation.{JsonSubTypes, JsonTypeInfo}
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
object GithubExample {
@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}")
}
}
}
```
The first part when we serialize and deserialize the `User` object works just fine. The code breaks on (7) when it tries to access `success.result.name` because `success.result` is somehow a `Map` instead of a `User`.
Here is the output:
```scala
(1) serializedUser: {"name":"John Smith","age":39}
(2) deserializedUser: User(John Smith,Some(39))
(3) deserializedUser.name: John Smith
(4) serializedSuccess: {"@type":"GithubExample$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 GithubExample$User
at GithubExample$.main(GithubExample.scala:55)
at GithubExample.main(GithubExample.scala)
```
As evidenced by the logs, the serialization seems to be working just fine. Is there something I need to change to get the deserialization working?
Hướng dẫn đóng góp
Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này
Đánh giá
Issue này chưa được đánh giá.