I'm using Flink's(1.7.2) kafka consumer. How to deserialize several case class that extends the same trait ? eg
import spray.json.{DefaultJsonProtocol, RootJsonFormat}
trait Foo
case class Boo(name: String) extends Foo
case class Buzz(name: String, age: Int) extends Foo
object Formats extends DefaultJsonProtocol{
implicit val booFormat: RootJsonFormat[Boo] =
jsonFormat1(Boo.apply)
implicit val buzzFormat: RootJsonFormat[Buzz] =
jsonFormat2(Buzz.apply)
}
I'm using kafka consumer with this DeserializationSchema
:
class FooSchema extends DeserializationSchema[Foo]{
@transient lazy val log = LoggerFactory.getLogger(this.getClass)
implicit val typeInfo = createTypeInformation[Foo]
override def deserialize(bytes: Array[Byte]): Foo = {
val foo = new String(bytes, StandardCharsets.UTF_8).parseJson
.convertTo[Foo] //doesn't compile, I need to deserialize to Boo and Buzz
log.debug(s"Received Boo")
foo
}
override def isEndOfStream(t: Foo): Boolean = false
override def getProducedType: TypeInformation[Foo] = createTypeInformation[Foo]
}
any idea will be greatly appreciated
Try spray-json-shapeless which can automatically derive decoders for ADTs like so:
sealed trait Foo
case class Boo(name: String) extends Foo
case class Buzz(name: String, age: Int) extends Foo
object MyFormats extends DefaultJsonProtocol with FamilyFormats {
implicit val formats = shapeless.cachedImplicit[JsonFormat[Foo]]
}
Remember to make the trait sealed
. Note that raw JSON needs to contain type
field disambiguator for rawJsonString.parseJson.convertTo[Foo]
to work, for example
object Main extends App {
import MyFormats._
val rawJsonBuzz =
"""
|{
| "name": "Picard",
| "age": 60,
| "type": "Buzz"
|}
""".stripMargin
val buzz = rawJsonBuzz.parseJson.convertTo[Foo]
println(buzz)
val rawJsonBoo =
"""
|{
| "name": "Picard",
| "type": "Boo"
|}
""".stripMargin
val boo = rawJsonBoo.parseJson.convertTo[Foo]
println(boo)
}
should output
Buzz(Picard,60)
Boo(Picard)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.