2013-05-01 34 views
5

Làm thế nào để bạn tạo đối tượng Json với các giá trị của các loại khác nhau?Làm thế nào để bạn tạo đối tượng Json với các giá trị của các loại khác nhau?

Tôi đang sử dụng phun json

Đây là mã

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

Nó hoạt động nhưng trông thật sự nặng nề. Có cách nào để xác định json với mã như thế này?

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 

Nó không làm việc nói rằng

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

nào tôi nhận được, loại từng lĩnh vực không được quy định tại thời gian biên dịch. Nhưng tại sao nó sẽ không hoạt động nếu serializer không phù hợp với mô hình nào?

Cảm ơn!

+0

Thư viện có thể hỗ trợ điều này. Nhưng nếu không, có một hàm 'implicit' nhận' String' và chuyển nó thành 'JsString' – Jatin

Trả lời

1

Bạn đang sử dụng phương pháp sai ở đây. Vì mục đích nhất quán, tôi đặc biệt khuyến khích bạn sử dụng case class.

Giả sử bạn có này

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

Và sau đó bạn sử dụng parsedecompose để đối phó với điều này.

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

Và nếu bạn muốn serialize một List[Image] để JSON:

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

Để phân tích một danh sách các hình ảnh từ JSON:

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

Sử dụng Option[SomeType] trong Imagecase class sẽ đối phó với thiếu thông số/tùy chọn tự động.

4

Tôi đồng ý với @ alex23 rằng phương pháp tiếp cận dựa trên lớp vỏ sẽ tốt hơn. Sử dụng spray-json, trước tiên bạn sẽ định nghĩa cấu trúc lớp vỏ của bạn cũng như phần mở rộng của DefaultJsonProtocol để mô tả các lớp vỏ mà bạn muốn có thể tuần tự hóa. Điều đó sẽ trông như thế này:

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

Sau đó, một phiên bản sửa đổi của các ví dụ của bạn sẽ trông như thế này:

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 

Lý do tại sao bạn đang nhìn thấy lỗi được mà phun json không biết làm thế nào để sắp xếp danh sách các bộ dữ liệu bạn đang tạo. Nếu bạn thực sự muốn sử dụng cấu trúc đó và không đi theo đường trường hợp của lớp, thì bạn có thể xem xét việc cung cấp một serializer tùy chỉnh cho List [(String, Any)]. Kiểm tra phần trong tài liệu phun-json có tiêu đề "Cung cấp JsonFormats cho các loại khác". Nếu bạn muốn đi tuyến đường này và cần thêm trợ giúp, hãy cho tôi biết.

Các vấn đề liên quan