16

当缺少必填字段时,是否可以让 json4s 不抛出异常?

当我从原始 json 字符串中“提取”对象时,它会抛出像这样的异常

org.json4s.package$MappingException: No usable value for pager
No usable value for rpp
Did not find value which can be converted into byte
    at org.json4s.reflect.package$.fail(package.scala:98)
    at org.json4s.Extraction$ClassInstanceBuilder.org$json4s$Extraction$ClassInstanceBuilder$$buildCtorArg(Extraction.scala:388)
    at org.json4s.Extraction$ClassInstanceBuilder$$anonfun$11.apply(Extraction.scala:396)

是否可以让它为 null ?

4

2 回答 2

20

这很简单,你必须使用Option和它的潜力,SomeNone

val json = ("name" -> "joe") ~ ("age" -> Some(35));
val json = ("name" -> "joe") ~ ("age" -> (None: Option[Int]))

但请注意,在上述情况下,match将为您的Option. 如果是None,它将完全从字符串中删除,因此不会反馈 null。

在相同的模式中,要解析不完整的 JSON,您可以使用case classwith Option

case class someModel(
    age: Option[Int],
    name: Option[String]
);
val json = ("name" -> "joe") ~ ("age" -> None);
parse(json).extract[someModel];

有一种方法不会抛出任何异常,那就是extractOpt

parse(json).extractOpt[someModel];

使用 scala API 复制它的一种方法是使用scala.util.Try

Try { parse(json).extract[someModel] }.toOption
于 2013-04-11T08:54:41.737 回答
7

在处理数据迁移时,我已经处理了这个问题,我希望使用默认值来填充未定义的字段。

我的解决方案是在提取结果之前将默认值合并到 JValue 中。

  val defaultsJson = Extraction.decompose(defaults)
  val valueJson = JsonUtil.jValue(v)
  (defaultsJson merge valueJson).extract[T]

JsonUtil.scala

  import org.json4s._

  object JsonUtil {
    import java.nio.charset.StandardCharsets.UTF_8
    import java.io.{InputStreamReader, ByteArrayInputStream}

    def jValue(json: String): JValue = {
      jValue(json.getBytes(UTF_8))
    }

    def jValue(json: Array[Byte]): JValue = {
      val reader = new InputStreamReader(new ByteArrayInputStream(json), UTF_8)
      native.JsonParser.parse(reader)
    }
  }
于 2014-09-22T21:26:45.230 回答