使用circe在scala中定义通用解码器
Define generic decoder in scala using circe
我正在尝试将我的 JsonUtils class 从 Json4s 切换到 circe
我发现很难解决解码器的通用实现问题。
我的 Json4s 函数看起来像这样:
implicit val formats = DefaultFormats
def extractValueFromJson[T](json: String, key: String)(implicit m: Manifest[T]): T = {
val parsed = parse(json).asInstanceOf[JObject]
val value =(parsed \ key).extract[T]
value
}
用法示例:
extractValueFromJson[String](jsonStr, keyInJson)
它运行良好
现在我已经尝试了与 circe 相同的功能:
implicit def decodeGeneric[A: Decoder](json: Json): Either[Error, A] = Decoder[A].decodeJson(json)
def extractValueFromJson[A: ClassTag, T](jsonStr: String, key: String)(implicit m: Manifest[T]): T = {
val json: String = jsonStr.asJson.noSpaces
decode[A](json) match {
case Left(error: Error) => throw error
case Right(value) => {
value.getClass.getDeclaredField(key).get(value).asInstanceOf[T]
}
}
}
编译时出现以下错误:
could not find implicit value for evidence parameter of type io.circe.Decoder[A]
[error] decode[A](json) match {
[error] ^
这是给定输入的期望输出
输入:
case class Bar(str: String)
val bar = Bar("just a string")
用法:
val test = extractValueFromJson[Bar,String](bar.asJson.noSpaces,"str")
输出:
just a string
我在这里做错了什么?
有没有办法定义通用解码器?
我在这里阅读了一些类似的问题,但还没有找到适合我需要的解决方案
你可以这样做:
def extractValueFromJson[A](jsonStr: String, key: String)(implicit decoder: Decoder[A]): A =
io.circe.parser.decode(jsonStr)(decoder.at(field = key)) match {
case Right(result) => result
case Left(error) => throw error
}
你可以这样使用:
extractValueFromJson[String](jsonStr = bar.asJson.noSpaces, key = "str")
// res: String = "just a string"
我正在尝试将我的 JsonUtils class 从 Json4s 切换到 circe
我发现很难解决解码器的通用实现问题。
我的 Json4s 函数看起来像这样:
implicit val formats = DefaultFormats
def extractValueFromJson[T](json: String, key: String)(implicit m: Manifest[T]): T = {
val parsed = parse(json).asInstanceOf[JObject]
val value =(parsed \ key).extract[T]
value
}
用法示例:
extractValueFromJson[String](jsonStr, keyInJson)
它运行良好
现在我已经尝试了与 circe 相同的功能:
implicit def decodeGeneric[A: Decoder](json: Json): Either[Error, A] = Decoder[A].decodeJson(json)
def extractValueFromJson[A: ClassTag, T](jsonStr: String, key: String)(implicit m: Manifest[T]): T = {
val json: String = jsonStr.asJson.noSpaces
decode[A](json) match {
case Left(error: Error) => throw error
case Right(value) => {
value.getClass.getDeclaredField(key).get(value).asInstanceOf[T]
}
}
}
编译时出现以下错误:
could not find implicit value for evidence parameter of type io.circe.Decoder[A]
[error] decode[A](json) match {
[error] ^
这是给定输入的期望输出
输入:
case class Bar(str: String)
val bar = Bar("just a string")
用法:
val test = extractValueFromJson[Bar,String](bar.asJson.noSpaces,"str")
输出:
just a string
我在这里做错了什么? 有没有办法定义通用解码器? 我在这里阅读了一些类似的问题,但还没有找到适合我需要的解决方案
你可以这样做:
def extractValueFromJson[A](jsonStr: String, key: String)(implicit decoder: Decoder[A]): A =
io.circe.parser.decode(jsonStr)(decoder.at(field = key)) match {
case Right(result) => result
case Left(error) => throw error
}
你可以这样使用:
extractValueFromJson[String](jsonStr = bar.asJson.noSpaces, key = "str")
// res: String = "just a string"