2017-02-13 34 views
0

我有以下的用例:JSON4S反序列化不带参数的名字

每一个类,我使用SERDE JSON4S有一个字段,名为ID。这ID可以是任何类型T <: Stringifiable,其中Stringifiable要求您的ID类型被散列为一个字符串。 Stringifiables也有构造函数,它们从字符串中重建它们。

我想将任何Stringifiable,例如ComplexIdentifier塞满到JSON ID: stringified_identifier。序列化很好地工作,但不幸的是,在反序列化过程中,JSON4S不会使用只有1个字符串构造函数的默认构造函数。它找到构造函数,但是如果标识符的签名为case class ComplexIdentifier(whatever: String),它将尝试从JString(stringified_identifier)中提取whatever名称。这失败了,所以MappingException被内部抛出。

有什么办法教JSON4S使用默认构造函数而不提取这样的值吗?只要使用JString的值并使用它构造Stringifiable就显而易见了。

谢谢!

回答

0

在Companion中使用apply方法可以使用String参数为ID类的构造函数重载。然后,只需使用一个自定义序列的所有身份证件类型

sealed abstract class Stringifiable {} 

case class ComplexIdentifier(whatever: List[Long]) extends Stringifiable 
case class SimpleIdentifier(whatever: Int) extends Stringifiable 

//Overload the default constructor 
object ComplexIdentifier { 
    def apply(s: String):ComplexIdentifier = { 
    ComplexIdentifier(s.split(",").map(_.toLong).toList) 
    } 
} 

case class MyClass(id: ComplexIdentifier, value: String) 

然后使用自定义序列:

case object ComplexIdentifierSerializer extends CustomSerializer[ComplexIdentifier] (formats => 
({ 
    case JString(id) => ComplexIdentifier(id) 
    case JNull => null 
}, 
{ 
    case x: ComplexIdentifier => JString(x.whatever.mkString(",")) 
})) 

最后,请务必在隐格式串行:

implicit val formats = DefaultFormats ++ List(ComplexIdentifierSerializer) 

println(parse(""" 
    { 
    "id": "1", 
    "value": "big value" 
    } 
    """).extract[MyClass]) 

    val c = MyClass(ComplexIdentifier("123,456"), "super value") 
    println(write(c))