2013-05-01 2 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 
    ^

는, 각 필드의 유형이 컴파일시에 정의되지 않은 것을 말하는 작동하지 않습니다. 하지만 serializer가 패턴 매칭을 어쨌든 수행하면 왜 작동하지 않을까요?

감사합니다.

+0

라이브러리가이를 지원할 수도 있습니다. 하지만 그렇지 않다면'String'을 받아'JsString'으로 변환하는'암시 적 (implicit) '함수를 가져야합니다. – Jatin

답변

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에 A :

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

처리됩니다 Imagecase classOption[SomeType] 사용 :

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

는 JSON에서 이미지의 목록을 구문 분석 누락 된/선택적 매개 변수.

4

나는 경우 클래스 기반의 접근 방식이 더 좋을 것 @ alex23에 동의합니다. 스프레이 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이 방법을 알고하지 않습니다됩니다 만들고있는 튜플 목록을 직렬화합니다. 이 구조체를 사용하고 case 클래스 라우트를 사용하지 않으려는 경우 List [(String, Any)]에 대한 사용자 정의 serializer를 살펴볼 수 있습니다. "다른 유형의 JsonFormats 제공"이라는 제목의 spray-json 문서 섹션을 확인하십시오. 이 길을 가고 더 많은 도움이 필요하면 알려주세요.