Как читать/записывать трейты с объектами case с помощью play-json

У меня есть следующая структура:

  sealed trait Animal {
    def name: String
    def kind: String
  }

  case object Dog extends Animal {
    override def name: String = "A"
    override def kind: String = "B"
  }

  case object Whale extends Animal {
    override def name: String = "C"
    override def kind: String = "B"
  }

Как я могу читать/записывать его в/из json с помощью play-json? Для writes это просто, а как насчет reads?


person zella    schedule 12.09.2019    source источник


Ответы (2)


Если вы хотите придерживаться объектов дела, вы можете определить пользовательский Writer /Reader

import play.api.libs.json._
implicit val w: Writes[Animal] = {
  case d @ _ => Json.obj(
    "name" -> d.name,
    "kind" -> d.kind
  )
}
Json.toJson(Dog)

Вы можете настроить его для обработки каждого объекта отдельно, чтобы вы могли обрабатывать случаи, когда вы вводите новые поля в объекте.

person Feyyaz    schedule 12.09.2019
comment
Даже при использовании object нет необходимости в пользовательском обработчике с последней версией Play-JSON. - person cchantep; 12.09.2019

Вам нужно case classes НЕ case objects, например:

sealed trait Animal {
    def name: String
    def kind: String
  }

  case class Dog(name: String = "A", kind: String = "B") extends Animal 

  case class Whale(name: String = "C", kind: String = "B") extends Animal

Или, если у вас есть статические значения, используйте перечисление из enumeratum.

person pme    schedule 12.09.2019
comment
Хорошо, но могу ли я защитить класс от значений, отличных от значений по умолчанию? - person zella; 12.09.2019
comment
Какой смысл в таком object? За исключением некоторых ограниченных тестов? - person cchantep; 12.09.2019
comment
@zella Я думаю, что перечисления - лучший способ - см. мою ссылку. - person pme; 12.09.2019