【发布时间】:2021-02-02 17:52:45
【问题描述】:
我正在处理an API,它需要一个 JSON 对象,其中一个值(blob)是一个字符串化的 JSON 对象:
{
"credential": {
"blob": "{\"access\":\"181920\",\"secret\":\"secretKey\"}",
"project_id": "731fc6f265cd486d900f16e84c5cb594",
"type": "ec2",
"user_id": "bb5476fd12884539b41d5a88f838d773"
}
}
我的域类是:
case class Credential(access: String, secret: String, projectId: String, userId: String)
对领域类进行编码很容易:
implicit val encoder: Encoder[Credential] = (a: Credential) => Json.obj(
"type" -> "ec2".asJson,
"blob" -> Map("access" -> a.access, "secret" -> a.secret).asJson.noSpaces.asJson,
"project_id" -> a.projectId.asJson,
"user_id" -> a.userId.asJson
)
但是解码要困难得多:
implicit val decoder: Decoder[Credential] = (c: HCursor) => for {
blobJsonString <- c.get[String]("blob")
blob <- decode[Json](blobJsonString).left.map(e => DecodingFailure(e.getMessage, c.downField("blob").history))
access <- blob.hcursor.get[String]("access")
secret <- blob.hcursor.get[String]("secret")
projectId <- c.get[String]("project_id")
userId <- c.get[String]("user_id")
} yield Credential(access, secret, projectId, userId)
我不喜欢这种实现,因为它迫使我依赖 circe-parser,并破坏了编码器/解码器提供的抽象层。
有没有办法实现一个以一般方式进行双重解码的解码器?
【问题讨论】: