Sttp, Circe, Json – 如何将Json反序列化为自定义对象?

huangapple go评论77阅读模式
英文:

Sttp, Circe, Json - how to deserialize Json to custom object?

问题

我有一个简单的案例类,用于模拟Http响应:

case class Other(name: String, age: Int)
case class MyResponse(id: String, name: String, others: List[Other])

我为它们创建了解码器:

implicit val decoderOther: Decoder[Other] = deriveDecoder[Other]
implicit val decoderMyResponse: Decoder[MyResponse] = deriveDecoder[MyResponse]

但是当我在sttp http客户端上调用它时:

basicRequest.(...).get(...).response(asJson[MyResponse].getRight).send(backend).map(_)

我遇到了一个Desarialization错误:

sttp.client3.DeserializationException: DecodingFailure at .id Missing required field

我不知道为什么它无法被正确解析。解码器看起来没问题。当我将MyResponse更改为circe的Json类时,它可以正常工作:

Response([{ "id": "121", "name": "test", "others": [] }])

但我想将其解析为我的模型。你能帮助我吗?

英文:

I have a simple case class which models Http response:

case class Other(name: String, age: Int)
case class MyResponse(id: String, name: String, others: List[Other])

I created decoders for them:

implicit val decoderOther: Decoder[Other] = deriveDecoder[Other]
implicit val decoderMyResponse: Decoder[MyResponse] = deriveDecoder[MyResponse]

But when I call it on sttp http client:

basicRequest.(...).get(...).response(asJson[MyResponse].getRight).send(backend).map(_) 

I got a Desarialization error:

sttp.client3.DeserializationException: DecodingFailure at .id Missing required field

I don't know why it cannot be parsed correctly. Decoders seems fine. When I change MyResponse to circe Json class it works fine:

Response([{ "id": "121", "name": "test", "others": [] }])

but I would like to parse it to my model. Can you help me?

答案1

得分: 2

如果您编写asJson[MyResponse],则需要使用Encoder而不是Decoder

因此,请添加以下内容:

implicit val encoderOther: Encoder[Other]           = deriveEncoder[Other]
implicit val encoderMyResponse: Encoder[MyResponse] = deriveEncoder[MyResponse]

您可以将EncoderDecoder替换为Codec

implicit val codecOther: Codec[Other]           = deriveCodec[Other]
implicit val codecMyResponse: Codec[MyResponse] = deriveCodec[MyResponse]
MyResponse("121", "test", List()).asJson.noSpaces
// {"id":"121","name":"test","others":[]}

如果您仍然遇到问题,请准备一个MCVE

英文:

If you write asJson[MyResponse] you need Encoder rather than Decoder.

So add

implicit val encoderOther: Encoder[Other]           = deriveEncoder[Other]
implicit val encoderMyResponse: Encoder[MyResponse] = deriveEncoder[MyResponse]

You can replace Encoder and Decoder with Codec

implicit val codecOther: Codec[Other]           = deriveCodec[Other]
implicit val codecMyResponse: Codec[MyResponse] = deriveCodec[MyResponse]
MyResponse("121", "test", List()).asJson.noSpaces
// {"id":"121","name":"test","others":[]}

https://scastie.scala-lang.org/DmytroMitin/W3wgn0gbRXyA1vRI6OyoUg/1

If you still experience issues please prepare MCVE.

huangapple
  • 本文由 发表于 2023年3月3日 19:05:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/75626278.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定