Scala:使用 circe.io 解码 Any[] 数组
Scala: decode Any[] array using circe.io
我有一个 Java 服务器创建一条如下所示的消息:
@SerializedName("message")
private String _message;
@SerializedName("args")
private Object[] _args;
现在在我的 Scala.js 应用程序中,我想使用类似以下内容反序列化此消息:
case class Notification(message: String, args: String*)
implicit val messageDecoder: Decoder[Notification] = (c: HCursor) => {
for {
message <- c.downField("message").as[String]
args <- c.downField("args").as[List[java.lang.Object]].map(_.toString)
} yield {
Notification(level, message, args)
}
}
但是,Scala 拒绝解码并出现以下错误:
implicit error;
[error] !I d: Decoder[List[Object]]
[error] Decoder.importedDecoder invalid because
[error] !I exported: Exported[Decoder[List[Object]]]
[error] Decoder.decodeCanBuildFrom invalid because
[error] !I d: Decoder[Object]
[error] ??Decoder.importedDecoder invalid because
[error] !I exported: Exported[Decoder[Object]]
[error]
[error] Decoder.decodeList invalid because
[error] !I evidence: Decoder[Object]
[error] ??Decoder.importedDecoder invalid because
[error] !I exported: Exported[Decoder[Object]]
[error] args <-
c.downField("args").as[List[Object]].map(_.toString)
[error] ^
[error] one error found
关于如何解码这个的任何想法?我只需要在结果上调用 map(toString)
。
编辑
当尝试做这样的事情时:
args <- c.downField("args").as[Array[Any]].map(_.toString)
我收到以下错误:
diverging implicit expansion for type io.circe.Decoder[A]
[error] starting with value decodeString in object Decoder
[error] args <-
c.downField("args").as[Array[Any]].map(_.toString)
[error] ^
[error] one error found
编辑 2
args <- c.downField("args").as[Seq[String]].map(_.toString)
编译,但未成功解析 json(左)。
编辑 3
发送的 json 的一个示例(在本例中为整数):
{
"message" : "{0} is smaller than {1}.",
"args" : [
1,
2
]
}
java 服务器也可以生成如下所示的 JSON:
{
"message" : "{0} is smaller than {1}. ({2})",
"args" : [
1,
2,
"Hello World!"
]
}
假设您的参数由 Int 和 String 组成,看看这是否适合您
case class Notification(message: String, args: String*)
object Notification {
implicit val decodeIntOrString: Decoder[Either[Int, String]] =
Decoder[Int].map(Left(_)).or(Decoder[String].map(Right(_)))
implicit val messageDecoder: Decoder[Notification] = Decoder.instance(c => {
for {
message <- c.downField("message").as[String]
args <- c.downField("args").as[List[Either[Int,String]]].map(_.toString)
} yield {
Notification(message, args)
}
})
}
这是测试用例
val json = """
{
"message" : "Hello" ,
"args" : [ 2, 3, 4,"good" ]
}
"""
println(decode[Notification](json))
我还要指出圈子讨论 https://github.com/circe/circe/issues/216,它或多或少讨论了相同的问题。我认为惯用的 circe 决定似乎是类型将派生反序列化。
将其添加为另一个答案,以保持历史清洁。
基本上,以下代码仅使用当前 json 值并使用它的字符串表示形式。
case class Notification(message: String, args: String*)
object Notification {
implicit val anyDecoder : Decoder[Any] = Decoder.instance(c => {
c.focus match {
case Some(x) => Right(x)
case None => Left(DecodingFailure("Could not parse", List()))
}
})
implicit val messageDecoder: Decoder[Notification] = Decoder.instance(c => {
for {
message <- c.downField("message").as[String]
args <- c.downField("args").as[List[Any]].map(_.toString)
} yield {
Notification(message, args)
}
})
}
测试用例是
val json = """
{
"message" : "Hello" ,
"args" : [ 2, 3.234, 4,"good", true ]
}
"""
println(decode[Notification](json))
我有一个 Java 服务器创建一条如下所示的消息:
@SerializedName("message")
private String _message;
@SerializedName("args")
private Object[] _args;
现在在我的 Scala.js 应用程序中,我想使用类似以下内容反序列化此消息:
case class Notification(message: String, args: String*)
implicit val messageDecoder: Decoder[Notification] = (c: HCursor) => {
for {
message <- c.downField("message").as[String]
args <- c.downField("args").as[List[java.lang.Object]].map(_.toString)
} yield {
Notification(level, message, args)
}
}
但是,Scala 拒绝解码并出现以下错误:
implicit error;
[error] !I d: Decoder[List[Object]]
[error] Decoder.importedDecoder invalid because
[error] !I exported: Exported[Decoder[List[Object]]]
[error] Decoder.decodeCanBuildFrom invalid because
[error] !I d: Decoder[Object]
[error] ??Decoder.importedDecoder invalid because
[error] !I exported: Exported[Decoder[Object]]
[error]
[error] Decoder.decodeList invalid because
[error] !I evidence: Decoder[Object]
[error] ??Decoder.importedDecoder invalid because
[error] !I exported: Exported[Decoder[Object]]
[error] args <-
c.downField("args").as[List[Object]].map(_.toString)
[error] ^
[error] one error found
关于如何解码这个的任何想法?我只需要在结果上调用 map(toString)
。
编辑
当尝试做这样的事情时:
args <- c.downField("args").as[Array[Any]].map(_.toString)
我收到以下错误:
diverging implicit expansion for type io.circe.Decoder[A]
[error] starting with value decodeString in object Decoder
[error] args <-
c.downField("args").as[Array[Any]].map(_.toString)
[error] ^
[error] one error found
编辑 2
args <- c.downField("args").as[Seq[String]].map(_.toString)
编译,但未成功解析 json(左)。
编辑 3
发送的 json 的一个示例(在本例中为整数):
{
"message" : "{0} is smaller than {1}.",
"args" : [
1,
2
]
}
java 服务器也可以生成如下所示的 JSON:
{
"message" : "{0} is smaller than {1}. ({2})",
"args" : [
1,
2,
"Hello World!"
]
}
假设您的参数由 Int 和 String 组成,看看这是否适合您
case class Notification(message: String, args: String*)
object Notification {
implicit val decodeIntOrString: Decoder[Either[Int, String]] =
Decoder[Int].map(Left(_)).or(Decoder[String].map(Right(_)))
implicit val messageDecoder: Decoder[Notification] = Decoder.instance(c => {
for {
message <- c.downField("message").as[String]
args <- c.downField("args").as[List[Either[Int,String]]].map(_.toString)
} yield {
Notification(message, args)
}
})
}
这是测试用例
val json = """
{
"message" : "Hello" ,
"args" : [ 2, 3, 4,"good" ]
}
"""
println(decode[Notification](json))
我还要指出圈子讨论 https://github.com/circe/circe/issues/216,它或多或少讨论了相同的问题。我认为惯用的 circe 决定似乎是类型将派生反序列化。
将其添加为另一个答案,以保持历史清洁。
基本上,以下代码仅使用当前 json 值并使用它的字符串表示形式。
case class Notification(message: String, args: String*)
object Notification {
implicit val anyDecoder : Decoder[Any] = Decoder.instance(c => {
c.focus match {
case Some(x) => Right(x)
case None => Left(DecodingFailure("Could not parse", List()))
}
})
implicit val messageDecoder: Decoder[Notification] = Decoder.instance(c => {
for {
message <- c.downField("message").as[String]
args <- c.downField("args").as[List[Any]].map(_.toString)
} yield {
Notification(message, args)
}
})
}
测试用例是
val json = """
{
"message" : "Hello" ,
"args" : [ 2, 3.234, 4,"good", true ]
}
"""
println(decode[Notification](json))