没有参数名称的

时间:2017-02-13 19:36:24

标签: json scala json4s

我有以下用例:

我使用JSON4S服务的每个班级都有一个名为ID的字段。此ID可以是任何类型T <: Stringifiable,其中Stringifiable要求将您的ID类型散列为字符串。 Stringifiables还有构造函数,可以从字符串重构它们。

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

有没有办法让JSON4S使用默认构造函数而不提取像这样的值?仅使用JString中的值并使用该值构造Stringifiable就显而易见了。

谢谢!

1 个答案:

答案 0 :(得分:0)

使用Companion中的apply方法使用String参数重载ID类的构造函数。然后只需为所有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))