Scala Play框架:无法从具有零值的JSON生成对象

发布于 2025-01-28 19:24:11 字数 1617 浏览 6 评论 0原文

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

@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中的null值正在导致创建measurement < /代码>对象将不成功。我如何成功处理空值并将其设置为生成的measurementModel对象?

I'm new to Scala and the Play Framework. I have written the following controller:

@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
      )

    ...
  }
...
}

Where the endpoint receives the following 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 looks like this:

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) {

}

Through testing I have seen that the null values in the JSON are causing the creation of the measurement object to be unsuccessful. How can I successfully handle null values and have them set in the generated MeasurementModel object?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

海风掠过北极光 2025-02-04 19:24:11

可以存储null的数据类型为 null 选项[]
考虑以下替代代码:
`

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

选项将int值包裹在的一些中,可以通过模式匹配提取。

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ëlJ所提到的,您应该在您的案例类中添加所需数据类型的选项

,以便解决方案可以将数据类型包装在期望为空的位置。喜欢:

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

The datatypes that can store null are Null and Option[].
Consider the following REPL code:
`

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

The Option wraps the Int value in Some, which can be extracted by pattern matching.

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

As Gaël J mentioned, you should add Option for the desired datatype in your case class

So the solution can be to wrap the datatype in option where you expect a null. Like:

{
"altitude": Option[Float], 
"sensor_type": Option[String], 
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文