Използвам вграден jerson с playframework 2 и всичко, което искам, е да сериализирам карта, съдържаща стойности от различен тип:
object AppWriter extends Writes[Application] {
def writes(app: Application): JsValue = {
Json.toJson(Map(
"id" -> app.getId.toString,
"name" -> app.getName,
"users" -> Seq(1, 2, 3)
))
}
}
В този случай имам:
No Json deserializer found for type scala.collection.immutable.Map[java.lang.String,java.lang.Object].
Try to implement an implicit Writes or Format for this type
Navigatin чрез рамков код показва, че има сериализатор за типове Map [String, V] неявна def mapWrites [V] .., но не мога да разбера защо не се прилага.
Може ли някой да ми помогне?
UPD: Намерих просто решение:
object AppWriter extends Writes[Application] {
def writes(app: Application): JsValue = {
Json.toJson(Map[String, JsValue](
"id" -> JsNumber(BigDecimal(app.getId)),
"name" -> JsString(app.getName),
"users" -> JsArray(Seq(1, 2, 3).map(x => JsNumber(x)))
))
}
}
но това не е толкова елегантно ...
Отговори:
1 за отговор № 1Стандартният начин да направите това е чрез създаване на JsObject
от отделните двойки ключ-стойност за полетата, а не чрез поставянето на двойките в карта. Например, ако приемете своето Application
изглежда така:
case class Application(getId: Int, getName: String)
Бихте могли да напишете:
import play.api.libs.json._, Json.toJson
implicit object AppWriter extends Writes[Application] {
def writes(app: Application): JsValue = JsObject(
Seq(
"id" -> JsNumber(app.getId),
"name" -> JsString(app.getName),
"users" -> toJson(Seq(1, 2, 3))
)
)
}
И тогава:
scala> toJson(Application(1, "test"))
res1: play.api.libs.json.JsValue = {"id":1,"name":"test","users":[1,2,3]}
Обърнете внимание, че не е необходимо да уточнявате как да сериализирате Seq[Int]
—По подразбиране Format
инстанциите ще свършат работата вместо вас.