首页 > 解决方案 > Scala:如何修复尝试使用 Circe 解码器解码 JSON 的类型不匹配错误

问题描述

在以下情况下,我需要一些帮助。我有一个带有注册请求的 JSON API。该请求采用 4 个参数:标准电话、密码、电子邮件和客户选择类型的人员参数。根据选择的类型,他们必须再指定一个参数:姓名或年龄。

当我收到一个 HTTP 请求时,我需要将它解码为我的请求对象。使用以下代码执行此操作会导致以下类型的编译错误:

type mismatch;
 found   : Unit
 required: io.circe.Decoder[RegistrationReq]

任何想法为什么会出现这种情况以及如何解决它?提前致谢!

import cats.effect.Sync
import cats.syntax.either._
import circe.jsonOf
import io.circe.{Decoder, DecodingFailure, HCursor}
import io.circe.generic.semiauto._
import io.circe.refined._
import io.circe.Decoder.Result
import org.http4s.EntityDecoder

trait RegJsonCodec {

  import JsonCodec._ //all common encoders and decoders come from there

  implicit val RegistrationReqDecoder: Decoder[RegistrationReq] = {

    def apply(c: HCursor): Result[RegistrationReq] =
      for {
        phone <- getPhone(c)
        password <- c.downField("password").as[Password]
        email <- c.downField("email").as[Email] //Password and Email are refined Strings
        person <- getPerson(c)
      } yield RegistrationReq(phone, password, email, person)
  }

  private def getPhone(c: HCursor): Either[DecodingFailure, Long] =
    c.downField("phone").as[Long].orElse {
      c.downField("phone").as[String].flatMap {
        str =>
          Either.catchNonFatal(str.toLong)
            .leftMap(e => DecodingFailure(e.getMessage, c.history))
      }
    }.flatMap(phone => Either.right(phone))

  private def getPerson(c: HCursor): Either[DecodingFailure, Person] = {
    c.downField("person").downField("type").as[String].flatMap { type =>

      c.downField("person").downField("name").as[String]
        .orElse(c.downField("person").downField("age").as[String]).flatMap { extra =>

        Either.catchNonFatal(Person.fromPair(type, extra))
          .leftMap(e => DecodingFailure(e.getMessage, c.history))
          .flatMap(person => Either.right(person))
      }
    }
  }

  implicit def requestEntityDecoder[F[_] : Sync]: EntityDecoder[F, RegistrationReq] = jsonOf[F, RegistrationReq]

}

object RegJsonCodec extends RegJsonCodec

标签: jsonscaladecodercirce

解决方案


推荐阅读