2015-05-09 19 views
2

鑑於以下情況下類:Scala的鍵/值的情況下類爲JSON

case class ValueItem(key: String, value: String) 

和下面的JSON格式:

implicit val valueItemFormat: Format[ValueItem] = (
     (__ \ "key").format[String] and 
     (__ \ "value").format[String])(ValueItem.apply, unlift(ValueItem.unapply)) 

一個ValueItem實例的JSON表示像

ValueItem("fieldname", "fieldValue") 

{ "key" : "fieldName" , "value" : "fieldValue" } 

我想知道如何得到一個JSON在平鍵/值序列一樣

{ "fieldName" : "fieldValue" } 
+0

我懷疑你可能有定義單獨讀取和寫入,而不是使用此格式。 – Daenyth

+0

是的,這是一個很好的觀點。我已經去過那裏了,但是我遇到了找到沒有參數名稱的恰當jspath的問題,但是知道位置。像「鑰匙」之類的東西來「價值」之前 – Dario

回答

1

我想不出一個很好的方式做到這一點使用組合程序,因爲大多數方法需要有一個更直接將路徑中的值映射到案例類字段。

下面是一個解決方案,可用於像{"fieldName" : "fieldValue"}這樣的對象。

import play.api.libs.json._ 
import play.api.data.validation.ValidationError 

implicit val fmt: Format[ValueItem] = new Format[ValueItem] { 

    def reads(js: JsValue): JsResult[ValueItem] = { 
     js.validate[JsObject].collect(ValidationError("Not a key-value pair")) { 
      case JsObject(Seq((key, str: JsString))) => ValueItem(key, str.value) 
     } 
    } 

    def writes(v: ValueItem): JsValue = Json.obj(v.key -> v.value) 

} 

我已經使出了手動定義readswrites,你可以看到。 Reads是棘手的部分,因爲我們不習慣將路徑名稱拉入case類。我們可以將validate作爲JsObject的對象第一個,然後collect對象匹配我們正在尋找的確切結構(只有一個鍵值對,其中值爲JsString)。 Writes更直接,因爲Json.obj可以做我們想要的。

在行動:

scala> Json.parse(""" { "fieldName" : "fieldValue" } """).validate[ValueItem] 
res0: play.api.libs.json.JsResult[ValueItem] = JsSuccess(ValueItem(fieldName,fieldValue),) 

scala> val item = ValueItem("myKey", "myValue") 
item: ValueItem = ValueItem(myKey,myValue) 

scala> Json.toJson(item) 
res2: play.api.libs.json.JsValue = {"myKey":"myValue"} 
+0

這真的很有幫助。非常感謝 – Dario

0

遊戲發佈它用於處理JSON獨立播放器框架模塊,Play WS

在關於閱讀JSON到case類博客文章,但寫的很相似。檢查出來的http://pedrorijo.com/blog/scala-json/

使用case類,並Play WS(已經包含在遊戲框架),你的情況下JSON和案例類之間的轉換有一個簡單的一行隱含

case class User(username: String, friends: Int, enemies: Int, isAlive: Boolean) 

object User { 
    implicit val userJsonFormat = Json.format[User] 
} 
相關問題