如果json不包含字段,如何使json4s提取失败

时间:2016-05-26 09:55:06

标签: json scala deserialization json4s

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

case class MyClass(list: List[String])

如果我现在尝试将一些任意json反序列化到这个case类中,那么如果缺少list字段则它不会失败。 是否有可能在提取过程中强制它失败?

代码示例:

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!

我需要它为失踪列表字段失败,就像它对字符串字段一样。 请帮忙。 THX!

1 个答案:

答案 0 :(得分:0)

解决方案:

您可以使用列表字段创建 MyClass 反序列化器以反序列化 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)
    }

我们可以看到上面的代码片段,当我们在案例类中遇到一个集合时, Json4S 将检索 Json AST中的字段通过构造函数参数名称( list ),如果找不到参数名称( list ),它将返回JNothing,但对于{{ 1}}在上面的代码片段中,它将创建一个新的集合(JNothing),而不会抛出错误。