我正在使用一个API,该API在响应中的多个层次上公开一个对象。例如,对于某些响应,我们返回:

{
  "error": {
    "code": "123",
    "description": "Description"
  }
}

但在其他情况下,它的响应为:
{
  "data": [
    {
      "message_id": "123",
      "error": {
        "code": "123",
        "description": "Description"
      }
    }
  ]
}

在这两种情况下,错误对象都是相同的,在两种情况下,我实际上都不关心其余的有效负载。我希望使用\\递归JsPath运算符,但是以下实现失败:
case class ErrorMessage(code: String, description: String)
implicit val errorMessageFormat = Json.format[ErrorMessage]

case class ErrorResponse(errors: Seq[ErrorMessage])
implicit val errorResponseFormat: Format[ErrorResponse] = Format(
  (__ \\ "error").read[Seq[ErrorMessage]].map(ErrorResponse),
  (__ \ "errors").write[Seq[ErrorMessage]].contramap((r: ErrorResponse) => r.errors)
)

这给出了一个错误:
JsError(List((//error,List(ValidationError(List(error.expected.jsarray),WrappedArray())))))

我了解原因:(__ \\ "error")返回Seq[JsValue],在我的读取调用中,期望JsArray

请问有个不错的办法吗?

最佳答案

由于第一部分已经是Seq,因此只需映射内部元素,就像映射单个对象一样。我对框架不是很熟悉(我主要是自己使用Json4s),但是根据您的描述,听起来像

ErrorResponse((__ \\ "error").map(_.read[Seq[ErrorMessage]]))

应该更接近你想要的。 (__ \\ "error")为您提供SeqJsValuesmap为每个JsValue做一些事情,read将单个JsValue转换为ErrorMessage,并将生成的Seq[ErrorMessage]传递给ErrorResponse构造函数。

关于json - Play Json递归读,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34059019/

10-09 23:40