2

我正在尝试使用我无法控制的 API,该 API 的文档记录不佳且有些不一致。这意味着有时,API 返回的类型与记录的类型或您通常看到的类型不同。对于这个例子,我们将看一个在我通常会看到字符串的地方返回一个数组的情况。这使得 API 很糟糕,但我真正的问题是:我怎样才能更容易地追踪这些东西?现在,错误看起来像这样:

No usable value for identifier
Do not know how to convert JArray(List(JString(3c8723eceb1a), JString(cba8849e7a2f))) into class java.lang.String

在破译问题之后(为什么JValue::toString不发出 JSON 字符串让我完全感到困惑),我可以弄清楚当我case class只能够处理Strings 时 API 返回了一个数组。伟大的。我的问题是,在我的对象模型和 JSON 的内容之间找到这种差异似乎比它应该做的要困难得多。

目前,这是我寻找解码错误的工作流程:

  1. 希望不良数据有某种识别标记。如果这不是真的,那么这是更多的猜测,您将不得不为每个看起来像坏位的条目重复以下步骤。
  2. 经历将JArray(List(JString(...), ...))错误消息转换为有效 JSON 的麻烦,希望我在获取数据的 API 端点上以相同的方式编码 JSON。如果这不是真的,那么我使用 JSON 格式化程序 ( jq) 来一致地格式化所有数据。
  3. 在源数据中找到解码错误的来源。
  4. 回溯数组和对象,以发现我需要如何更改对象模型以更准确地表示从 API 返回给我的数据。

一些背景知识:我来自 C++,为此我推出了自己的 JSON 反序列化框架。使用我构建的库时的等效错误是:

Error decoding value at result.taskInstances[914].subtasks[5].identifier: expected std::string but found array value (["3c8723eceb1a","cba8849e7a2f"]) at 1:4084564

这是我使用手卷库时的过程:

  1. 将预期类型 ( std::string) 与实际找到的数据() 进行比较,["3c8723eceb1a","cba8849e7a2f"]并更改我的数据模型以获取源中数据的路径 ( result.taskInstances[914].subtasks[5].identifier)

正如你所看到的,我可以立即跳到我实际遇到的问题上。

我的问题是:有没有办法更快地调试我的数据模型和我从 API 返回的结果之间的不一致?

我正在使用json4s-native_2.10版本3.2.8


一个简化的例子:

{ "property": ["3c8723eceb1a", "cba8849e7a2f"] }

不与 Scala 啮合class

case class Thing(property: String)
4

1 回答 1

0

最好的解决方案是在 Scala 中使用 Try http://www.scala-lang.org/api/current/#scala.util.Try,但不幸的是 json4s API 不能。

所以,我认为你应该使用 Scala Option 类型http://www.scala-lang.org/api/current/#scala.Option

在 Scala 中,以及更普遍的函数式语言中,Options 用于表示可以存在或不存在的对象(如 nil 值)。

对于处理解析失败,您可以使用 parse(str).toOption,这是一个返回 Option[JValue] 的函数,您可以对结果值进行模式匹配。

为了处理将数据提取提取到案例类中,您可以使用 extractOpt 函数对值进行模式匹配。

您可以阅读此答案:https ://stackoverflow.com/a/15944506/2330361

于 2014-04-26T05:28:15.850 回答