json - 解码大小写类,大约为String或Int

标签 json scala circe

我使用一些 Rest API 响应包含一种“混合”字段的 json。混合我的意思是它可以采用不同类型的值。就我而言, ObjectStringInt 是允许的。 Object 本身由 1 个 Int 和 1 个 String 组成。

我需要解码的对象如下所示:

一世

{
   field1: 32,
   ...
   value: {
      id: 23,
      text: "text"
   }
}


{
   field1: 32,
   ...
   value: 21
}


{
   field1: 32,
   ...
   value: "value"
}

如何处理circe中的此类对象?

最佳答案

假设您的案例类是:

@JsonCodec(decodeOnly = true)
case class X(id: Int, text: String)

然后我可以假设您的字段是以下类型:
type Mixed = X Either Int Either String

解码它可能看起来像:
implicit val mixedDecoder: Decoder[Mixed] = 
  Decoder[X].map[Mixed](x => Left(Left(x))) or Decoder[Int].map[Mixed](i => Left(Right(i))) or Decoder[String].map[Mixed](s => Right(s))

如果您定义了它们的组合方式,您可以为 Either 派生编解码器:左胜、右胜或您喜欢的任何方式:
implicit def eitherDecode[L: Decoder, R: Decoder]: Decoder[L Either R] =
  Decoder[L].map[L Either R](Left(_)) or Decoder[R].map[L Either R](Right(_))

或者,您可以创建自己的 ADT(密封特征 + 案例类),然后编写手写解码器以避免使用鉴别器字段。

最重要的是,您必须以某种方式表达您正在解码的类型中的多态性(以一种理智的方式 - Any 不计算在内),然后提供一个解码器来解码它。然后你可以简单地使用它:
@JsonCodec(decodeOnly = true)
case class BigClass(field1: String, value: Mixed)

关于json - 解码大小写类,大约为String或Int,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62102137/

相关文章:

android - 如何使用 Parcelable 和 onClickListeners?

scala - Enumeration自动推导找不到Encoder

scala - 使用 Circe 解码消息时,是否可以从 DecodingFailure 中提取无效值

javascript - Backbone 集合 toJSON 返回集合对象

java - 如何 "split"在不同 JSON 数组之间映射值?

javascript - 查找 JSON 对象大小而不将其解析为字符串

scala - 如何更改项目的sbt版本

scala - 使用 JobTest 类在 Hadoop 中运行 Scalding 测试作业

scala - 如何在使用 git 库的 IntelliJ IDEA 中设置 scala 项目

scala - 貘自定义编解码器