2014-04-10 3 views
13

고객 시리얼 화기를 쓰고 있습니다. 해당 Serializer에서 나는 어떻게 든 말하고 싶습니다 : "그리고이 일은 당신이 이미 serialize하는 방법을 안다."json4s를 사용하여 객체를 AST로 직렬화하는 방법은 무엇입니까?

내 현재의 접근 방식은 다음과 같습니다

import org.json4s.native.Serialization._ 
    import org.json4s.JsonDSL.WithBigDecimal._ 

    object WindowSerializer extends CustomSerializer[Window](format => 
     ([omitted], 
     { 
      case Window(frame, size) => 

      ("size" -> size) ~ 
      ("frame" -> parse(write(frame))) 
     })) 

parse(write(frame)) 그 일이 추악하고 비효율적입니다. 그것을 고치는 방법?

답변

23

런타임 리플렉션을 사용하여 JValue을 생성하는 Extraction.decompose(a: Any)(implicit formats: Formats): JValue을 호출 할 수 있습니다.

import org.json4s._ 
import org.json4s.jackson.JsonMethods._ 
import org.json4s.JsonDSL._ 
import java.util.UUID 

case class Thing(name: String) 
case class Box(id: String, thing: Thing) 

class BoxSerializer extends CustomSerializer[Box](format => ({ 
    case jv: JValue => 
    val id = (jv \ "id").extract[String] 
    val thing = (jv \ "thing").extract[Thing] 
    Box(id, thing) 
}, { 
    case b: Box => 
    ("token" -> UUID.randomUUID().toString()) ~ 
     ("id" -> box.id) ~ 
     ("thing" -> Extraction.decompose(box.thing)) 
})) 

implicit val formats = DefaultFormats + new BoxSerializer 

val box = Box("1000", Thing("a thing")) 

// decompose the value to JSON 
val json = Extraction.decompose(box) 
println(pretty(json)) 
// { 
// "token" : "d9bd49dc-11b4-4380-ab10-f6df005a384c", 
// "id" : "1000", 
// "thing" : { 
//  "name" : "a thing" 
// } 
// } 

// and read a value of type Box back from the JSON 
println(json.extract[Box]) 
// Box(1000,Thing(a thing)) 
+0

좋아요! 나는 내일 시험 할 것이다. – mjaskowski

+0

위대한 작품! 'Extraction.decompose'가 사용되도록 수정 한 예제 만 포함하면이 대답을 받아 들일 것입니다. – mjaskowski

+0

질문에 Window 클래스를 추가 할 수 있습니까? –

관련 문제