Scala Json десериализуется с помощью null или Option [Int] - PullRequest
3 голосов
/ 17 октября 2019

У меня есть следующий класс дел, определенный в Scala

case class BitmexTradeData(
      foreignNotional: Option[Int],
      grossValue: Option[Int],
      homeNotional: Option[Double],
      price: Double,
      side: Side,
      size: Double,
      symbol: String,
      tickDirection: String,
      timestamp: Instant,
      trdMatchID: String
)

Теперь, когда я получаю следующую строку json, которую я хотел десериализовать обратно в BitmexTradeData:

{
  "timestamp": "2019-10-17T01:34:00.000Z",
  "symbol": ".BTRXXBT",
  "side": "Buy",
  "size": 0,
  "price": 0.00000187,
  "tickDirection": "PlusTick",
  "trdMatchID": "00000000-0000-0000-0000-000000000000",
  "grossValue": null,
  "homeNotional": null,
  "foreignNotional": null
}

Iполучить следующую ошибку:

spray.json.DeserializationException: Expected Int as JsNumber, but got null

способ десериализации этого заключается в следующем:

msg.parseJson.convertTo[BitmexTradeData]

Я ожидаю, что выходной объект будет BitmexTradeData Object с foreignNotional в качестве необязательного .empty, как несколько разэти значения равны нулю.

1 Ответ

0 голосов
/ 17 октября 2019

Если вы не заблокированы для использования spray-json, добавьте jsoniter-scala в свой список зависимостей:

libraryDependencies ++= Seq(
  "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-core"   % "1.0.0" % Compile,
  "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-macros" % "1.0.0" % Provided // required only in compile-time
)

Добавьте импорт, определите структуры данных и получите кодек:

import com.github.plokhotnyuk.jsoniter_scala.macros._
import com.github.plokhotnyuk.jsoniter_scala.core._

sealed trait Side
case object Buy extends Side
case object Sell extends Side

case class BitmexTradeData(
  foreignNotional: Option[Int],
  grossValue: Option[Int],
  homeNotional: Option[Double],
  price: Double,
  side: Side,
  size: Double,
  symbol: String,
  tickDirection: String,
  timestamp: Instant,
  trdMatchID: String  // <-- Here you can use java.util.UUID for validation, less memory allocations and more efficient parsing/serialization
)

implicit val codec: JsonValueCodec[BitmexTradeData] =
  JsonCodecMaker.make(CodecMakerConfig.withDiscriminatorFieldName(None))

После этого вы можете проанализировать и распечатать ваш ввод:

val data = readFromArray("""{
                           |  "timestamp": "2019-10-17T01:34:00.000Z",
                           |  "symbol": ".BTRXXBT",
                           |  "side": "Buy",
                           |  "size": 0,
                           |  "price": 0.00000187,
                           |  "tickDirection": "PlusTick",
                           |  "trdMatchID": "00000000-0000-0000-0000-000000000000",
                           |  "grossValue": null,
                           |  "homeNotional": null,
                           |  "foreignNotional": null
                           |}""".stripMargin.getBytes("UTF-8"))

println(data)

Вывод будет:

BitmexTradeData(None,None,None,1.87E-6,Buy,0.0,.BTRXXBT,PlusTick,2019-10-17T01:34:00Z,00000000-0000-0000-0000-000000000000)
...