2017-06-22 41 views
1

我試着寫了下面的類斯卡拉讀取與嵌套可選屬性

case class User(id: String, imageId: Option[String]) 

的JSON我有看起來像這樣的讀取對象:

{ 
    "id": 1 
    "image": { "id" : 2 } 
} 

然而,「形象」領域可能不存在,或者可能爲空。 我讀看起來是這樣的:

implicit val userReader: Reads[User] = (
(JsPath \ "id").read[String] and 
(JsPath \ "image" \ "id").readNullable[String] 
) (User.apply _) 

但是,這似乎並沒有工作,我仍然得到一個錯誤,當它發現沒有圖像的樣本。 'ValidationError [...] error.path.missing [...]/image/id'

這怎麼解決?我不想創建一個Image類,我不打算在任何地方使用它。

回答

2

我認爲這個問題是來自您試圖讀取StringidInt的事實。你應該介意你的類型在你的JSON /閱讀器。

兩個選項

  • 如果id是一個真正的Int,讀它作爲一個Int
  • 如果idString,改變你的JSON

如果你還是希望有一個String在你的課堂上,你可以這樣做:

(JsPath \ "image" \ "id").readNullable[Int].map(_.toString) 
+0

這顯然是一個問題,但它並沒有抱怨,因爲我試過n沒有圖像的例子,所以它看不到類型不匹配。 我把它切換到字符串,我仍然得到相同的錯誤。 – Dragos

+0

同樣適用於根目錄中的'id' –

0

您忘記了兩個元素之間的逗號("id""image")。這就是解析器似乎缺少/image/id路徑的原因。

有各種驗證JSON結構的工具,例如https://jsonlint.com/。 所以,你的JSON結構應該是這樣的:

{ 
    "id": 1, 
    "image": { 
     "id": 2 
    } 
} 
0

我可能會遲到,但這裏是一個解決辦法:

implicit val userReader: Reads[User] = (
    (JsPath \ "id").read[String] and 
    (JsPath \ "image" \ "id").readNullable[String].orElse((__ \ "dummy").readNullable[String]) 
) (User.apply _) 

並不完美,但它工作得很好

更好的解決辦法是直接在orElse裏面投了Js Reads(JsSuccess(None:Option[Int]))但我還沒有做到這一點...