Scala:用一个对象读取一个Json并转换这个对象

时间:2017-03-10 01:52:06

标签: arrays json scala

我正在尝试构建可以读取Json并将其转换为对象的内容。问题是:这个对象里面有另一个对象的数组。

我试图这样做:

case class Account(number: String, description: String, operations: Array[Operation])
object Account {
  implicit object AccountFormat extends Format[Account]{
    def reads( json: JsValue): JsResult[Account] = {
      val number      = (json \ "number").as[String]
      val description = (json \ "description").as[String]
      val operations  = (json \ "operations").as[Array[Operation]]
      JsSuccess(Account(number, description, operations))
    }

    def writes(account: Account): JsValue = {
      val accountAsList = Seq("number"      -> JsString(account.number),
        "description" -> JsString(account.description),
        "operations"  -> JsString(account.operations.toString()))
      JsObject(accountAsList)
    }

  }
}

case class Operation( operationType: String, operationValue: String, operationDate: String)

Object Operation {
  implicit object OperationFormat extends Format[Operation]{
    def reads( json: JsValue): JsResult[Operation] = {
      val operationType  = (json \ "operationType").as[String]
      val operationValue = (json \ "operationValue").as[String]
      val operationDate  = (json \ "operationDate").as[String]

      JsSuccess(Operation(operationType, operationValue, operationDate))
    }

    def writes(operation: Operation): JsValue = {
      val operationAsList = Seq(
        "operationType"  -> JsString(operation.operationType),
        "operationValue" -> JsString(operation.operationValue),
        "operationDate"  -> JsString(operation.operationDate) )

    JsObject(operationAsList)
    }
}

如您所见,在Account类中,我有操作属性,即操作数组。接下来,我有操作的结构。

我需要在这个结构中收到一个JSON:

{"number": "123", "description":"Bank Account", [
  {"operationType": "A", "operationValue: "10.00", "operationDate": "100317"}, 
  {"operationType": "A", "operationValue: "10.00", "operationDate": "100317"} ]
}

但是,当我尝试执行此过程时,我收到了下一个错误:

No Json deserializer found for type Array[models.Operation]. Try to implement an implicit Reads or Format for this type.

我知道我做了一件非常错误的事情并且我在睡眠中失明了,但我无法找到错误的位置以及解决方法。

谢谢!

1 个答案:

答案 0 :(得分:0)

看起来你正在使用Play Json,我的回答基于

你有一些错误,我已经包含了一个完整的工作示例程序。 Play提供了ReadsWrites的良好文档,我建议您查看更多信息。

import play.api.libs.json._
import play.api.libs.functional.syntax._

object Main {

  case class Account(number: String, description: String, operations: Array[Operation])
  object Account {

    // Example reads
    implicit val reads: Reads[Account] = (
      (JsPath \ "number").read[String] and
      (JsPath \ "description").read[String] and
      (JsPath \ "operations").read[Array[Operation]]
    )(Account.apply _)

    // Example writes
    implicit val writes: Writes[Account] = (
      (JsPath \ "number").write[String] and
      (JsPath \ "description").write[String] and
      (JsPath \ "operations").write[Array[Operation]]
    )(unlift(Account.unapply _))
  }

  case class Operation(operationType: String, operationValue: String, operationDate: String)
  object Operation {

    implicit val reads: Reads[Operation] = (
      (JsPath \ "operationType").read[String] and
      (JsPath \ "operationValue").read[String] and
      (JsPath \ "operationDate").read[String]
    )(Operation.apply _)

    implicit val writes: Writes[Operation] = (
      (JsPath \ "operationType").write[String] and
      (JsPath \ "operationValue").write[String] and
      (JsPath \ "operationDate").write[String]
    )(unlift(Operation.unapply _))
  }

  def main(args: Array[String]): Unit = {

    // Also your json was invalid, I cleaned it up
    val testString =
      """
        |{
        |    "number": "123",
        |    "description": "BankAccount",
        |    "operations": [
        |        {
        |            "operationType": "A",
        |            "operationValue": "10.00",
        |            "operationDate": "100317"
        |        },
        |        {
        |            "operationType": "A",
        |            "operationValue": "10.00",
        |            "operationDate": "100317"
        |        }
        |    ]
        |}
      """.stripMargin

    val account = Json.parse(testString).as[Account]
    println(account.number)

  }

}