json - 根据其他字段指定的类型读取 JSON 字段

标签 json scala playframework

我有如下 JSON:

{
  "properties" : {
    "timestamp" : "1970-01-01T01:00:00+01:00",
    "attributes" : [
      {
        "name" : "Weather",
        "value" : "Cloudy",
        "fieldDataType" : "string"
      },
      {
        "name" : "pH",
        "value" : 7.2,
        "fieldDataType" : "double"
      },
      {
        "name" : "Quality Indicator",
        "value" : 2,
        "fieldDataType" : "integer"
      }
    ]
}

我想使用 Play JSON 库来解析它。我已经能够处理“时间戳”,但在解析“值”字段时遇到困难,因为它的类型是由“fieldDataType”确定的。到目前为止我已经:

sealed trait AttributeValue
case class AttributeInt(value: Integer) extends AttributeValue
case class AttributeDouble(value: Double) extends AttributeValue
case class AttributeString(value: String) extends AttributeValue

case class Attribute (name: String, value: AttributeValue)

object Attribute {    
    implicit val attributeReads: Reads[Attribute] = (
        (JsPath \ "name").read[String] and
        (JsPath \ "fieldDataType").read[String] // ???
    )(Attribute.apply _)
}

我希望能够读取“fieldDataType”,然后根据其值读取“value”字段。因此,如果“fieldDataType”是字符串,则将“值”读取为字符串,如果“fieldDataType”是“整数”,则将“值”读取为整数,等等。

最佳答案

首先,我确实允许自己将您的 ​​AttributeInt 声明更改为:

case class AttributeInt(value: Int) extends AttributeValue

使用默认的Int解析器

接下来你可以定义这样的Reads提供者:

val attributeByDatatype: PartialFunction[String, JsPath => Reads[AttributeValue]] = {
  case "integer" => _.read[Int].map(AttributeInt)
  case "double" => _.read[Double].map(AttributeDouble)
  case "string" => _.read[String].map(AttributeString)
}

作为 PartialFunction 不仅允许它处理特定的数据类型,还可以提供有关它知道什么数据类型和不知道什么数据类型的信息,这对于 Reads.collect 方法很有用,而生成的 Reads 可以作为 flatMap

的目标

现在您可以按如下方式更改您的attributeReads:

object Attribute {
  implicit val attributeReads: Reads[Attribute] = (
      (JsPath \ "name").read[String] and
      (JsPath \ "fieldDataType")
      .read[String]
      .collect(ValidationError("datatype unknown"))(attributeByDatatype)
      .flatMap(_(JsPath \ "value"))
  )(Attribute.apply _)
}

关于json - 根据其他字段指定的类型读取 JSON 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33204107/

相关文章:

python - 使用 Python 请求过滤来自网站 API 的 json 响应

scala - Apache 弗林克 : changing state parameters at runtime from outside

java - SimpleDateFormat.parse 生成不一致的结果

java - 使用 Play Framework 调试命令时出错

json - 如何将动态复杂的 json 解析为 dart 对象或模型

c# - 在 C# 中获取 JSON POST 数据

php - Zend_JSON :Encode messing up - why?

list - 如何创建具有特定类型的 List 的包装器

playframework - Play Framework 2.3 - 不检测变化

java - 类型安全激活器 NoSuchMethodError