2013-05-01 121 views
5

你如何創建不同類型值的Json對象?如何用不同類型的值創建Json對象?

我使用噴霧JSON

下面是代碼

val images : List[JsObject] = fetchImageUrls(url).map((url: String) => { 
    JsObject(List(
     "link_path" -> JsString(url), 
     "display_name" -> JsString("image"), 
     "size" -> JsString(""), 
     "modified" -> JsString(""), 
     "thumbnail" -> JsString(url), 
     "filename" -> JsString("image"), 
     "is_dir" -> JsBoolean(x = false), 
     "thumb_exists" -> JsBoolean(x = true))) 
    }) 

val jsonAst: JsObject = JsObject(List(
    "client" -> JsString("urlimages"), 
    "view" -> JsString("thumbnails"), 
    "contents" -> JsArray(images) 
)) 

它的工作原理,但看起來真的很重。有沒有辦法像這樣的代碼來定義json?

val images : List[List[(String, Any)]] = fetchImageUrls(url).map((url: String) => { 
    List(
    "link_path" -> url, 
    "display_name" -> "image", 
    "size" -> "", 
    "modified" -> "", 
    "thumbnail" -> url, 
    "filename" -> "image", 
    "is_dir" -> false, 
    "thumb_exists" -> true) 
}) 

val jsonAst = List(
    "client" -> "urlimages", 
    "view" -> "thumbnails", 
    "contents" -> images 
).toJson 

它不工作,說

Cannot find JsonWriter or JsonFormat type class for List[(String, Object)] 
    ).toJson 
    ^

這一點我得到的,每個字段的類型沒有在編譯時定義。但是,如果串行器無論如何都進行模式匹配,爲什麼它不工作?

謝謝!

+0

圖書館可能會支持這一點。但是,如果沒有,有一個'隱式'函數需要'String'並將其轉換爲'JsString' – Jatin 2013-05-01 06:59:52

回答

1

你要在這裏錯誤的做法。爲了一致性的目的,我強烈建議您使用case class

說你有這個

case class Image(
    url: String, 
    size: Double, 
    properties: Map[String][String] 
    optionalProperty: Option[String] 
    // etc. 
); 

然後使用parsedecompose來處理這個問題。

val image = parse(jsonString).extract[Image]; // extracts an Image from JSON. 
val jsonForImage: JValue = decompose(image); // serializes an Image to JSON. 

如果你想序列化List[Image]到JSON:

def serialize(images: List[Image]) : JValue = { 
    for (image <- images) 
     yield decompose(image); 
}; 

爲了解析從JSON圖像列表:

val images: List[Image] = parse(jsonString).extract[List[Image]]; 

Imagecase class將涉及使用Option[SomeType]缺失/可選參數自動。

4

我同意@ alex23基於案例類的方法會更好。使用spray-json,您首先需要定義您的案例類結構以及DefaultJsonProtocol的擴展,以描述您希望能夠序列化的案例類。這將是這樣的:

case class Image(link_path:String, display_name:String, size:Option[String], 
    modified:Option[String], thumbnail:String, filename:String, is_dir:Boolean, thumb_exists:Boolean) 
object Image 

case class UrlImages(client:String, view:String, contents:List[Image]) 
object UrlImages 

object MyJsonProtocol extends DefaultJsonProtocol { 
    implicit val imageFormat = jsonFormat8(Image.apply) 
    implicit val urlImagesFormat = jsonFormat3(UrlImages.apply) 
} 

然後,你的榜樣的修改版本是這樣的:

import MyJsonProtocol._ 
val images : List[Image] = fetchImageUrls(url).map((url: String) => { 
    Image(url, "image", None, None, url, "image", false, true)  
}) 

val jsonAst = UrlImages("urlimages", "thumbnails", images).toJson 

爲什麼你看到這個錯誤的原因是,噴霧JSON不知道如何序列化你正在創建的元組列表。如果你真的想使用這種結構而不去案例類路由,那麼你可以考慮爲List [(String,Any)]提供一個自定義序列化程序。查看名爲「爲其他類型提供JsonFormats」的spray-json文檔中的部分。如果你想走這條路,需要更多幫助,請告訴我。

相關問題