我有一个案例类,它只是这样的集合的包装:
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!
答案 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
),而不会抛出错误。