gpt4 book ai didi

scala - Circe 从蛇盒键解析 json

转载 作者:行者123 更新时间:2023-12-03 16:13:28 26 4
gpt4 key购买 nike

我有以下案例类:

final case class Camel(firstName: String, lastName: String, waterPerDay: Int)

和circe配置:
object CirceImplicits {

import io.circe.syntax._
import io.circe.generic.semiauto._
import io.circe.{Encoder, Decoder, Json}
import io.circe.generic.extras.Configuration

implicit val customConfig: Configuration =
Configuration.default.withSnakeCaseMemberNames.withDefaults
implicit lazy val camelEncoder: Encoder[Camel] = deriveEncoder
implicit lazy val camelDecoder: Decoder[Camel] = deriveDecoder
}

没关系,在对此进行测试时:
val camel = Camel(firstName = "Camelbek", lastName = "Camelov", waterPerDay = 30)

private val camelJ = Json.obj(
"firstName" -> Json.fromString("Camelbek"),
"lastName" -> Json.fromString("Camelov"),
"waterPerDay" -> Json.fromInt(30)
)

"Decoder" must "decode camel types" in {
camelJ.as[Camel] shouldBe Right(camel)
}

但是这个测试没有通过:
val camel = Camel(firstName = "Camelbek", lastName = "Camelov", waterPerDay = 30)

private val camelJ = Json.obj(
"first_name" -> Json.fromString("Camelbek"),
"last_name" -> Json.fromString("Camelov"),
"water_per_day" -> Json.fromInt(30)
)

"Decoder" must "decode camel types" in {
camelJ.as[Camel] shouldBe Right(camel)
}

如何正确配置 circe 以便能够在蛇的情况下使用 key 解析 json?

我正在使用 circe 版本 0.10.0

最佳答案

解决方案 1

Circe 从您的案例类实例中获取字段名称并使用游标遍历 JSON,尝试获取每个字段名称的值并尝试将其转换为您想要的类型。

这意味着您的解码器将无法处理这两种情况。

解决这个问题的方法是写两个解码器:

  • 基本解码器(deriveEncoder 可以工作)
  • 使用 HCursor 浏览您的 JSON 并获取蛇形大小写键的编码器

  • val decoderDerived: Decoder[Camel] = deriveDecoder
    val decoderCamelSnake: Decoder[Camel] = (c: HCursor) =>
    for {
    firstName <- c.downField("first_name").as[String]
    lastName <- c.downField("last_name").as[String]
    waterPerDay <- c.downField("water_per_day").as[Int]
    } yield {
    Camel(firstName, lastName, waterPerDay)
    }

    然后你可以使用 Decoder#or 将这两个解码器合二为一

    implicit val decoder: Decode[Camel] = decoderDerived or decoderCamelSnake

    Decoder#or 将尝试使用第一个解码器进行解码,如果失败,它将尝试使用第二个解码器。

    解决方案 2

    如果您只接受camel_case 输入,那么您可以使用 @ConfiguredJsonCodec来自 "io.circe" %% "circe-generic-extras" % circeVersion包裹。请注意,要使用此注释,您还需要包含天堂编译器插件。
    addCompilerPlugin(
    "org.scalamacros" % "paradise" % "2.1.1" cross CrossVersion.full
    )

    @ConfiguredJsonCodec
    case class User(
    firstName: String,
    lastName: String
    )

    object User {
    implicit val customConfig: Configuration = Configuration.default.withSnakeCaseMemberNames
    }

    val userJson = User("John", "Doe").asJson
    println(userJson)
    // { "first_name" : "John", "last_name" : "Doe" }

    val decodedUser = decode[User](userJson.toString)
    println(decodedUser)
    // Right(User("John", "Doe"))

    另请注意,您不需要编写自定义解码器和编码器派生器,因为该 Configuration 会为您执行此操作。

    关于scala - Circe 从蛇盒键解析 json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55867077/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com