2011-07-25 42 views
5

Giả sử tôi có cấu trúc sau đây tôi muốn serialize trong Json:làm thế nào để "làm phẳng" biểu diễn JSon của một đối tượng hỗn hợp?

case class A(name:String) 

case class B(age:Int) 

case class C(id:String, a:A,b:B) 

Tôi đang sử dụng thang máy-json "write (...)", nhưng tôi muốn san bằng cấu trúc nên thay vì:

{ id:xx , a:{ name:"xxxx" }, b:{ age:xxxx } } 

tôi muốn nhận được:

{ id:xx , name:"xxxx" , age:xxxx } 

Trả lời

1

Nếu A và B có nhiều lĩnh vực mà bạn sẽ muốn có một cách tiếp cận hơi khác nhau:

import net.liftweb.json._ 
import net.liftweb.json.JsonAST._ 
import net.liftweb.json.JsonDSL._ 

implicit val formats = net.liftweb.json.DefaultFormats 
implicit def cToJson(c: C): JValue = (("id" -> c.id):JValue) merge (Extraction decompose c.a) merge (Extraction decompose c.b) 
val c1 = C("c1", A("a name", "a nick", "an alias"), B(11, 111, 1111)) 
Printer pretty (JsonAST render c1) 
res0: String = 
{ 
    "id":"c1", 
    "name":"a name", 
    "nick":"a nick", 
    "alias":"an alias", 
    "age":11, 
    "weight":111, 
    "height":1111 
} 
0

bạn có thể khai báo một đối tượng D mới với các lĩnh vực (id, tên, tuổi) và tải các giá trị mà bạn muốn trong constructor sau đó serialize lớp đó để json. Có thể có cách khác nhưng cách này sẽ hiệu quả.

+0

Vâng, nó là một ví dụ. A và B có 10 trường mỗi, và lý do chính để có nó là không có 20 trường trong C, các kiểu đề xuất của bạn đánh bại mục đích :) – GClaramunt

4

Sử dụng transform phương pháp trên JValue:

import net.liftweb.json._ 
import net.liftweb.json.JsonAST._ 
implicit val formats = net.liftweb.json.DefaultFormats 
val c1 = C("c1", A("some-name"), B(42)) 
val c1flat = Extraction decompose c1 transform { case JField(x, JObject(List(jf))) if x == "a" || x == "b" => jf } 
val c1str = Printer pretty (JsonAST render c1flat) 

Kết quả:

c1str: String = 
{ 
    "id":"c1", 
    "name":"some-name", 
    "age":42 
} 
Các vấn đề liên quan