【问题标题】:Process json with different data type in Circe在 Circe 中处理具有不同数据类型的 json
【发布时间】:2018-01-23 02:53:28
【问题描述】:

在我的例子中,同一个 json 字段可能有不同的数据类型。示例:

"need_exp":1500

"need_exp":"-"

如何处理这种情况?我知道它可以由parse 处理或使用自定义编码器,但这是一个非常复杂的 json 文本,有没有办法在不重写整个解码器的情况下解决这个问题(例如,只需 “tell” 解码器将need_exp 字段中的所有Int 转换为String)?

【问题讨论】:

  • 使用自定义解码器检查 Json 种类
  • 如果字段是Option[Int] 呢?

标签: java json scala circe


【解决方案1】:

它被称为析取,可以使用 Scala 标准Either 类进行编码。 只需将 json 映射到以下类:

case class Foo(need_exp: Either[String, Int])

【讨论】:

    【解决方案2】:

    我的解决方案是使用自定义解码器。重写一小部分 JSON 就可以了。

    比如有一个简单的JSON:

    {  
       /*many fields*/
       "hotList":[/* ... many lists inside*/],
       "list":[ {/*... many fields*/
             "level_info":{  
                "current_exp":11463,
                "current_level":5,
                "current_min":10800,
                "next_exp":28800 //there is the problem
             },
             "sex":"\u4fdd\u5bc6"},/*...many lists*/]
    }
    

    这种情况下,我不需要重写整个JSON编码器,只需要写一个level_info的自定义编码器:

    implicit val decodeUserLevel: Decoder[UserLevel] = (c: HCursor) => for
    {
        current_exp <- c.downField("current_exp").as[Int]
        current_level <- c.downField("current_level").as[Int]
        current_min <- c.downField("current_min").as[Int]
        next_exp <- c.downField("next_exp").withFocus(_.mapString
        {
            case """-""" => "-1"
            case default => default
        }).as[Int]
    } yield
    {
        UserLevel(current_exp, current_level, current_min, next_exp)
    }
    

    它成功了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-04
      • 2017-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-08
      • 1970-01-01
      • 2020-08-15
      相关资源
      最近更新 更多