繁体   English   中英

Scala Play Framework:无法从具有空值的 json 生成对象

[英]Scala Play Framework: cannot generate object from json with null values

我是 Scala 和 Play 框架的新手。 我编写了以下控制器:

@Singleton
class MyController @Inject()(val controllerComponents: ControllerComponents) extends BaseController {

  implicit val newMeasurementJson: OFormat[MeasurementModel] = Json.format[MeasurementModel]

  def addMeasurement(): Action[AnyContent] = Action { implicit request =>
    val content = request.body

    val jsonObject: Option[JsValue] = content.asJson
    val measurement: Option[MeasurementModel] =
      jsonObject.flatMap(
        Json.fromJson[MeasurementModel](_).asOpt
      )

    ...
  }
...
}

端点接收以下 JSON 的位置:

{
    "sensor_id": "1029", 
    "sensor_type": "BME280", 
    "location": 503, 
    "lat": 48.12, 
    "lon": 11.488, 
    "timestamp": "2022-04-05T00:34:24", 
    "pressure": 94667.38, 
    "altitude": null, 
    "pressure_sealevel": null, 
    "temperature": 3.91, 
    "humidity": 65.85
}

MeasurementModel模型如下所示:

case class MeasurementModel(
                        sensor_id: String,
                        sensor_type: String,
                        location: Int,
                        lat: Float,
                        lon: Float,
                        timestamp: String,
                        pressure: Float,
                        altitude: Int,
                        pressure_sealevel: Int,
                        temperature: Float,
                        humidity: Float) {

}

通过测试,我看到 JSON 中的空值导致创建measurement对象不成功。 如何成功处理空值并将它们设置在生成的MeasurementModel对象中?

可以存储 null 的数据类型是NullOption[] 考虑以下 REPL 代码:`

scala> val mightBeIntOrNull: Option[Int] = Option(1)
val a: Option[Int] = Some(1)
scala> val mightBeIntOrNull: Option[Int] = null
val a: Option[Int] = null

Option将 Int 值包装在Some中,可以通过模式匹配提取。

scala> val mightBeIntOrNull: Option[Int] = Option(1)
val mightBeIntOrNull: Option[Int] = Some(1)

scala> mightBeIntOrNull match {
 | case Some(myIntVal) => println("This is an integer :" + myIntVal)
 | case _ => println("This might be a null")
 | }
This is an integer :1

scala> val mightBeIntOrNull: Option[Int] = null
val mightBeIntOrNull: Option[Int] = null

scala> mightBeIntOrNull match {
 | case Some(myIntVal) => println("This is an integer :" + myIntVal)
 | case _ => println("This might be a null")
 | }
This might be a null

正如 Gaël J 提到的,您应该在案例类中为所需的数据类型添加选项

因此,解决方案可以是将数据类型包装在您期望为空的选项中。 喜欢:

{
"altitude": Option[Float], 
"sensor_type": Option[String], 
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM