Десериализация JSON на основе поля в полезной нагрузке в Scala
У меня есть аналогичный вопрос с десериализацией JSON на основе полей в.Net (C#), но я делаю это в Scala.
У меня есть приложение, которое потоковое в 2-х типов объектов JSON (учетная запись и пользователь).
Учетная запись:
{
"data_type": "account",
"id": 1,
"type": "Trial",
"created_at": 1523982003,
}
Пользователь:
{
"data_type": "user",
"id": 1,
"account_id": 1,
"department": "Finance"
"created_at": 1523982122
}
Мне нужно десериализовать два вышеупомянутых объекта JSON на основе поля data_type
в Scala
с помощью Circe
библиотека.
Как я могу это сделать?
1 ответ
Этот фрагмент работает для меня в Аммоните:
import $ivy.`io.circe:circe-core_2.12:0.9.3`, io.circe._
import $ivy.`io.circe:circe-generic_2.12:0.9.3`, io.circe.generic._
import $ivy.`io.circe:circe-generic-extras_2.12:0.9.3`, io.circe.generic.extras._
interp.load.plugin.ivy("org.scalamacros" % "paradise_2.12.4" % "2.1.1")
implicit val config: Configuration = Configuration.
default.
withSnakeCaseMemberNames.
withDiscriminator("data_type").
copy(transformConstructorNames = _.toLowerCase)
{
@ConfiguredJsonCodec
sealed trait InputEntity
object InputEntity {
@ConfiguredJsonCodec case class Account(id: Long, `type`: String, createdAt: Long) extends InputEntity
@ConfiguredJsonCodec case class User(id: Long, accountId: Long, department: String, createdAt: Long) extends InputEntity
}
}
import $ivy.`io.circe:circe-parser_2.12:0.9.3`, io.circe.parser._
val accountJson = """
{
"data_type": "account",
"id": 1,
"type": "Trial",
"created_at": 1523982003
}
"""
val account = decode[InputEntity](accountJson)
// account: Either[Error, InputEntity] = Right(Account(1L, "Trial", 1523982003L)
val userJson = """
{
"data_type": "user",
"id": 1,
"account_id": 1,
"department": "Finance",
"created_at": 1523982122
}
"""
val user = decode[InputEntity](userJson)
// user: Either[Error, InputEntity] = Right(User(1L, 1L, "Finance", 1523982122L))
(Кстати: у вас были синтаксические ошибки в примерах JSON, которые приводили к сбою синтаксического анализатора, поэтому я исправил их в коде выше).
Наиболее важным здесь является
Configuration
отio.circe.generic.extras._
который определяет поле дискриминатора,- сохраняя классы как тип суммы,
- если вы используете аннотации для генерации кодеков, замените
@JsonCodec
с@ConfiguredJsonCodec
,
На самом деле, вы также можете заменить их String
с перечислениями и читать createdAt
как LocalDateTime
или аналогичные, но это было бы за рамками этого вопроса.