没有参数名称的JSON4S反序列化

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了没有参数名称的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是显而易见的。

谢谢!

答案

使用Companion中的applymethod使用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))

以上是关于没有参数名称的JSON4S反序列化的主要内容,如果未能解决你的问题,请参考以下文章

使用 Jackson 从 XML 到 POJO 的反序列化问题:没有从字符串值反序列化的字符串参数构造函数/工厂方法

没有从字符串值('1074')反序列化的字符串参数构造函数/工厂方法

Protobuf-Net 无法在没有无参数构造函数的情况下反序列化记录

没有从字符串值反序列化的字符串参数构造函数/工厂方法('2018-12-14')

Jackson MismatchedInputException(没有从字符串值反序列化的字符串参数构造函数/工厂方法)

在 JSON 反序列化期间没有为“System.String”类型定义无参数构造函数