【问题标题】:Scala Json Deserialize with null or Option[Int]Scala Json 使用 null 或 Option[Int] 反序列化
【发布时间】:2020-02-13 20:25:48
【问题描述】:

我在 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
)

现在当我得到以下我想反序列化回BitmexTradeData的json字符串时:

{
  "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
}

我收到以下错误:

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

我反序列化的方式如下:

msg.parseJson.convertTo[BitmexTradeData]

我期望的输出是 BitmexTradeData 对象,其中 foreignNotional 为 optional.empty,因为有时这些值为空。

【问题讨论】:

    标签: json scala spray


    【解决方案1】:

    如果您没有被锁定为仅使用 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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-17
      • 2021-06-11
      • 1970-01-01
      • 2017-12-14
      • 2022-11-19
      • 2015-02-28
      • 2014-07-02
      • 1970-01-01
      相关资源
      最近更新 更多