scala 是否可以在缺少必需字段时使 json4s 不抛出异常?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15943957/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 05:09:53  来源:igfitidea点击:

Is it possible to make json4s not to throw exception when required field is missing?

scalajson4s

提问by expert

Is it possible to make json4s not to throw exception when required field is missing ?

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

When I "extract" object from raw json string it throws exception like this one

当我从原始 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.apply(Extraction.scala:396)

Is it possible just to let it be null ?

是否可以让它为 null ?

回答by flavian

It's quite simple, you have to use Optionand its potentials, Someand None.

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

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

Beware though, in the above case a matchwill be performed for your Option. If it's None, it will be completely removed from the string, so it won't feed back null.

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

In the same pattern, to parse incomplete JSON, you use a case classwith Option.

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

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

There is a method which won't throw any exception, and that is extractOpt

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

parse(json).extractOpt[someModel];

A way to replicate that with the scala API would be to use scala.util.Try:

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

Try { parse(json).extract[someModel] }.toOption

回答by user364952

I've dealt with this problem when dealing with data migrations, and I wanted default values to fill undefined fields.

我在处理数据迁移时已经处理过这个问题,我想要默认值来填充未定义的字段。

My solution was to merge the defaults into the JValue before extracting the result.

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

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

JsonUtil.scala

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)
    }
  }