/ / Jerkson. Серіалізація карти на JsValue - scala, playframework-2.0, jerkson

Джерксон. Серіальна карта до JsValue - scala, playframework-2.0, jerkson

Я використовую вбудований 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

Навігація через рамковий код показує, що існує серіалізатор для типів 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 екземпляри зроблять роботу за вас.