I have one class which extends a trait as shown below:
case class Phone(number: String)
trait Person {
def name: String
def phones: Seq[Phone]
}
case class Employee(name: String, phones: Seq[Phone] = Seq.empty) extends Person
As shown above, Employee
class extends Person
trait.
I am trying to serialize and then deserialize one object of type Employee
as shown below:
implicit val formats = DefaultFormats
val emp: Person = Employee("foo")
val c = write(emp)
val e2 = parse(c).extract[Person]
Object emp
gets serialized properly
emp: Person = Employee(foo,List())
c: String = {"name":"foo","phones":[]}
but parse(c).extract[Person]
method fails with following exception:
org.json4s.package$MappingException: No constructor for type Person,
JObject(List((name,JString(foo)), (phones,JArray(List()))))
I tried to add FieldSerializer
like below but got same exception.
implicit val formats = DefaultFormats + FieldSerializer[Employee with Person]()
So I started writing custom serializer which looks like below:
case object PersonSerializer extends CustomSerializer[Person](formats => (
{
case JObject(
List(
JField("name", JString(name)),
JField("phones", JArray(List(phones)) )
)
) => Employee(name, phones)
},
{
case Employee(name, phones) => JObject(JField("name", JString(name)))
}
))
but this serializer fails to compile with following error:
type mismatch;
found : org.json4s.JsonAST.JValue
required: Seq[Phone]
) => Employee(name, phones)
So can you please help me with either writing custom serializer or to convert JValue
to Seq[Phone]
?
I don't think your actual problem is the one you think it is--you can't extract a Person, it's a trait! I'd extract an Employee, instead; if you need it to be a Person, just cast it to a Person after extraction.