2014-04-02 44 views
1

我正在嘗試使用一個API,我無法控制哪個文檔有點差,並且有點不一致。這意味着API有時會返回與記錄或通常看到的內容不同的類型。對於這個例子,我們將看一個數組返回的地方,我通常會看到一個字符串的情況。這使得一個糟糕的API,但我真正的問題是:我怎樣才能更輕鬆地追蹤這些東西?現在,這些錯誤是這個樣子:調試json4s讀取反序列化錯誤

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字符串是完全令人費解的我),我可以計算出API返回數組時,我我的case class只能夠處理String s。大。我的問題是,找到我的對象模型和JSON內容之間的這種差異似乎比它應該顯得更加困難。

目前,這是我的工作流程,追捕解碼錯誤:

  1. 希望壞的數據具有某種識別標識的。如果這不是真的,那麼這是更多的猜測,你將不得不重複以下步驟看起來像壞點。
  2. 通過將JArray(List(JString(...), ...))從錯誤消息轉換爲有效的JSON的麻煩,希望我在API端點以相同方式編碼JSON我從中獲取數據。如果不是這樣,那麼我使用JSON格式器(jq)來一致地格式化所有數據。
  3. 在解碼錯誤源於的源數據中找到位置。
  4. 通過數組和對象回溯,以發現我需要如何更改我的對象模型,以更準確地表示從API返回的數據。

一些背景:我來自C++,在那裏我爲自己推出了自己的JSON反序列化框架。使用我建庫時的等效錯誤是:有,這是該數據相比

  1. 看所期望的類型(std::string):

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

    這用我的手挽庫時,是我的過程居然發現(["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) 
+0

你能粘貼案例JSON的例子嗎? –

回答

0

最好的解決辦法是使用嘗試在斯卡拉http://www.scala-lang.org/api/current/#scala.util.Try,但不幸的是json4s API不能。

所以,我認爲你應該使用Scala Option類型http://www.scala-lang.org/api/current/#scala.Option

在Scala中,更一般的功能語言中,選項用於表示可以在那裏或不在的對象(如一個零值)。

對於句柄解析失敗,可以使用parse(str).toOption,它是一個返回Option [JValue]的函數,您可以對結果值進行模式匹配。

爲了處理提取數據提取到案例類中,可以使用extractOpt函數對值進行模式匹配。

你可以閱讀這個答案:https://stackoverflow.com/a/15944506/2330361

+0

感謝您的建議,但這不是我的問題。使用'Option [T]'不會給我任何東西,因爲無效的格式會被忽略(這是完全不可接受的)。問題是來自序列化庫的錯誤消息沒有幫助。我需要嚴格的序列化和良好的錯誤消息,沒有Scala JSON庫似乎提供。 –