【问题标题】:How can I make json4s extract fail if json doesn't contain field如果 json 不包含字段,如何使 json4s 提取失败
【发布时间】:2016-05-26 09:55:06
【问题描述】:

我有一个案例类,它只是这样的集合的包装器:

case class MyClass(list: List[String])

如果我现在尝试将一些任意 json 反序列化到这个案例类中,如果列表字段丢失,它不会失败。 是否可以在提取过程中强制它失败?

代码示例:

import org.json4s.jackson.JsonMethods.parse

implicit val formats = org.json4s.DefaultFormats

val json = parse("""{ "name": "joe" }""")

case class MyClass(list: List[String])

val myClass = json.extract[MyClass] // Works!
assert(myClass.list.isEmpty)


case class MyClass2(test: String)
val myClass2 = json.extract[MyClass2] // Fails!

我需要它为缺少的列表字段失败,就像它为字符串字段所做的那样。 请帮忙。谢谢!

【问题讨论】:

    标签: json scala deserialization json4s


    【解决方案1】:

    解决方案:

    您可以创建一个 MyClass 反序列化器以使用 List 字段反序列化 MyClass,例如:

      class MyClassSerializer extends Serializer[MyClass] {
        private val MyClassClass = classOf[MyClass]
    
        override def deserialize(implicit format: Formats): PartialFunction[(TypeInfo, JValue), MyClass] = {
          case (TypeInfo(MyClassClass, _), json) => json match {
            case JObject(JField("list", JArray(l)) :: _) =>
              MyClass(l.map(i => i.extract[String]))
            case x => throw new MappingException("Can't convert " + x + " to MyClass")
          }
        }
    
        override def serialize(implicit format: Formats): PartialFunction[Any, JValue] = ???
      }
    

    原因缺少List 字段无法用Exception 解析在Extraction.scala中:

      private class CollectionBuilder(json: JValue, tpe: ScalaType)(implicit formats: Formats) {
        private[this] val typeArg = tpe.typeArgs.head
        private[this] def mkCollection(constructor: Array[_] => Any) = {
          val array: Array[_] = json match {
            case JArray(arr)      => arr.map(extract(_, typeArg)).toArray
            case JNothing | JNull => Array[AnyRef]()
            case x                => fail("Expected collection but got " + x + " for root " + json + " and mapping " + tpe)
          }
    
          constructor(array)
        }
    

    我们可以看到上面的代码sn-p,当遇到case类中的一个集合时,Json4S会检索Json AST 由构造函数参数名(list),如果找不到参数名(list),则返回JNothing,但为@987654328 @在上面的代码sn-p中,它会创建一个新的集合(case JNothing | JNull => Array[AnyRef]())而不抛出错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-14
      • 1970-01-01
      • 2021-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-04
      • 1970-01-01
      相关资源
      最近更新 更多