java - Scala:使用 circe.io 解码 Any[] 数组

标签 java json scala decoding

我有一个 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$2: 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!"
  ]
}

最佳答案

将其添加为另一个答案,以保持历史记录干净。

基本上,以下代码仅适用于当前 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 - Scala:使用 circe.io 解码 Any[] 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53011166/

相关文章:

scala - 范围内变量的模式匹配 (Scala)

java - 从访问者计算机上的网页运行 java 类文件?

java - MVC 实践下何时创建新的类/arrayList 与何时仅依赖数据库

java - Oauth 进程中从 JIRA 获取请求 token 时出错

javascript - 使用ajax更新文本框中的值

javascript - 通过在 Javascript 中通过 "var"传递属性名称来获取 JSON 属性值

json - jq 根据另一个属性的值有条件地添加一个新属性

java - JavaFx 中各阶段之间的通信(使用 *.fxml)

scala - 如何组合两个 Future[JsArray]?

scala - 一次带有文件上传extractRequestContext和案例类的Akka HTTP API服务?