Skip to content

Instantly share code, notes, and snippets.

@gregakespret
Created November 5, 2014 19:27
Show Gist options
  • Save gregakespret/95e74f28551edc8a90c6 to your computer and use it in GitHub Desktop.
Save gregakespret/95e74f28551edc8a90c6 to your computer and use it in GitHub Desktop.
Polymorphic Deserialization Jackson using custom subtypes with default class fallback
import com.fasterxml.jackson.annotation.JsonSubTypes.Type
import com.fasterxml.jackson.annotation.{JsonTypeName, JsonSubTypes, JsonTypeInfo, JsonProperty}
import com.fasterxml.jackson.databind.{ObjectMapper,DeserializationFeature}
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "clazz",
defaultImpl = classOf[ScreenObject]
)
@JsonSubTypes(Array(
new Type(value = classOf[CreativeUnit], name = "CreativeUnit"),
new Type(value = classOf[Screen], name = "Screen"),
new Type(value = classOf[ScreenObject], name = "ScreenObject"),
new Type(value = classOf[NestedContainer], name = "NestedContainer"),
new Type(value = classOf[Button], name = "Button")
))
trait View {
@JsonProperty("viewName") def name: String
def localId: Int
def parentLocalId: Int
}
case class CreativeUnit(
@JsonProperty("viewName") name: String,
localId: Int,
parentLocalId: Int
) extends View {
def supportsAccidentalityDetection = name == "modal"
}
case class Screen(
@JsonProperty("viewName") name: String,
localId: Int,
parentLocalId: Int,
isMaster: Boolean
) extends View {
def title = name
}
case class ScreenObject(
@JsonProperty("viewName") name: String,
localId: Int,
parentLocalId: Int
) extends View
case class Button(
@JsonProperty("viewName") name: String,
localId: Int,
parentLocalId: Int
) extends View
case class NestedContainer(
@JsonProperty("viewName") name: String,
localId: Int,
parentLocalId: Int
) extends View
object PolymorphicDeseserialization {
def main(args: Array[String]): Unit = {
val mapper = new ObjectMapper with ScalaObjectMapper
mapper.registerModule(DefaultScalaModule)
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
val events = List(
"""{"name": "viewShown", "clazz": "Screen", "viewName": "Screen 1", "localId": "2", "parentLocalId": 1, "isMaster": false}""",
"""{"name": "viewShown", "clazz": "Video", "viewName": "Video 1", "localId": "3", "parentLocalId": 1}""",
"""{"name": "viewShown", "clazz": "Button", "viewName": "Button 1", "localId": "4", "parentLocalId": 1}"""
)
val deserialized = events.map(e => mapper.readValue[View](e))
println(deserialized)
// List(Screen(Screen 1,2,1,false), ScreenObject(Video 1,3,1), Button(Button 1,4,1))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment