scala - Which JSON serialization library would fit to the following case? -
i've got following case: i'd serialize scala case classes extend parent class var of type java.util.uuid. serialization of case classes should happen without configuration of them - no annotations , definition of custom formats. serialization hints may situated in parent class.
i tried sjson, reflection based serialization can't serialize uuid types , type based serialization forces me define formats every case class. json serialization library best fit case?
here's 1 solution lift json.
import java.util.uuid import net.liftweb.json._ import net.liftweb.json.jsonast._ import net.liftweb.json.jsondsl._ import net.liftweb.json.serialization._ sealed abstract class parent { def uuid: uuid } case class foo(uuid: uuid, name: string) extends parent object uuidtest extends application { implicit val formats = serialization.formats(notypehints) + new uuidserializer val f = foo(uuid.randomuuid, "foo") val ser = write(f) println(ser) val f2 = read[foo](ser) assert(f == f2) // special serializer uuid type class uuidserializer extends serializer[uuid] { private val class = classof[uuid] def deserialize(implicit format: formats): partialfunction[(typeinfo, jvalue), uuid] = { case (typeinfo(class, _), json) => json match { case jobject(jfield("mostsig", jint(m)) :: jfield("leastsig", jint(l)) :: nil) => new uuid(m.longvalue, l.longvalue) case x => throw new mappingexception("can't convert " + x + " uuid") } } def serialize(implicit format: formats): partialfunction[any, jvalue] = { case x: uuid => ("mostsig" -> x.getmostsignificantbits) ~ ("leastsig" -> x.getleastsignificantbits) } } }
it prints:
{"uuid":{"mostsig":-8054689529719995935,"leastsig":-5722404370736228056},"name":"foo"}'
another solution uses custom serializer parent type.
sealed abstract class parent { var uuid: uuid = uuid.randomuuid } case class foo(name: string) extends parent object uuidtest extends application { implicit val formats = serialization.formats(notypehints) + new parentserializer val f = foo("foo") val ser = write(f) println(ser) val f2 = read[foo](ser) assert(f == f2) // special serializer parent type class parentserializer extends serializer[parent] { def deserialize(implicit format: formats): partialfunction[(typeinfo, jvalue), parent] = { case (t@typeinfo(cl, _), json) if (classof[parent].isassignablefrom(cl)) => val x = extraction.extract(json, t)(defaultformats).asinstanceof[parent] x.uuid = (for { jfield("mostsig", jint(m)) <- json jfield("leastsig", jint(l)) <- json } yield new uuid(m.longvalue, l.longvalue)).head x } def serialize(implicit format: formats): partialfunction[any, jvalue] = { case x: parent => extraction.decompose(x)(defaultformats) ++ jfield("mostsig", x.uuid.getmostsignificantbits) ++ jfield("leastsig", x.uuid.getleastsignificantbits) } } }
Comments
Post a Comment