Как превратить json в класс case, когда класс case имеет только одно поле
В игре 2.1 чтение используется для сортировки Json для объектов. Но как я могу это сделать, когда класс case имеет только одно поле. Идеам, который работает для большего количества полей, не работает, поскольку одно поле "и" не используется. Таким образом, я не получаю FunctionBuilder.
Следующий код дает мне несоответствие типа. Как я могу это исправить?
case class Data(stamm: Seq[String])
implicit val dataReads = (
(__ \ "stamm").read(Reads.list[String])
)(Data)
Ответы
Ответ 1
Комбинаторы Json не работают для класса case с одним полем.
Паскаль (автор этого API) объяснил эту ситуацию здесь
https://groups.google.com/forum/?fromgroups=#!starred/play-framework/hGrveOkbJ6U
Существуют некоторые обходные пути, которые работают, как этот:
case class A(value: List[Int])
val areads = (__ \ 'value).read[List[Int]].map{ l => A(l) } // covariant map
Ответ 2
Как ответил Жюльен, вы можете прочитать классы отдельных полей, используя это:
case class Person(name: String)
val personReads: Reads[Person] =
(__ \ "name").read[String].map { name => Person(name) }
Просто добавьте, если вы хотите написать:
val personWrites: Writes[Person] =
(__ \ "name").write[String].contramap { (person: Person) => person.name }
Или формат (чтение и запись):
val personFormat: Format[Person] =
(__ \ "name").format[String].inmap(name => Person(name), (person: Person) => person.name)
Для записи и форматирования вам необходимо импортировать это:
import play.api.libs.functional.syntax._
Ответ 3
Основываясь на ответе @yokomizor, я нашел простейшее решение для создания Formatter
для
case class Person(name: String)
val personFormatter: Format[Person] =
(__ \ "full_name").format[String].inmap(Person.apply, unlift(Person.unapply))
Ответ 4
Даже более простое решение, чем принятое:
case class A(value: String)
val reads = (__ \ "key").read[String].map(A.apply)