Scala 案例有 22 个字段,但在 scala 2.11.5 中的 play-json 有问题

Scala case has 22 fields but having issue with play-json in scala 2.11.5

我们目前使用的是 scala 2.11.5,我的 class 中的 1 个有 22 个字段。

  case class CreateTransactionRequest(name: Option[String],
                                  balance: Option[BigDecimal],
                                  amount: BigDecimal,
                                  currency: String,
                                  dueDate: Option[DateTime],
                                  orderDate: DateTime,
                                  billing: Option[CreateAddressRequest],
                                  shipping: Option[CreateAddressRequest],
                                  status: String,
                                  email: String,
                                  paymentMethod: String,
                                  paymentTerm: Option[String],
                                  deliveryMethod: Option[String],
                                  source: String,
                                  attachments: Option[String],
                                  agent: Option[String],
                                  orders: Option[Set[CreateOrderRequest]],
                                  otherCharges: Option[Seq[CreateTransactionOtherChargeRequest]],
                                  notes: Option[Seq[CreateNoteRequest]],
                                  subscribers: Option[Seq[String]],
                                  trackingId: Option[String],
                                  acquisition: Option[String])

implicit val readsCreateTransactionRequest: Reads[CreateTransactionRequest] = Json.reads[CreateTransactionRequest]

环顾四周,我发现了一个解决方案并应用了它

val fields1to12: Reads[(Option[String], Option[BigDecimal], BigDecimal, String, Option[DateTime], DateTime, Option[CreateAddressRequest], Option[CreateAddressRequest], String, String, String, Option[String])] = (
    (__ \ "name").read[Option[String]] and
    (__ \ "balance").read[Option[BigDecimal]] and
    (__ \ "amount").read[BigDecimal] and
    (__ \ "currency").read[String] and
    (__ \ "dueDate").read[Option[DateTime]] and
    (__ \ "orderDate").read[DateTime] and
    (__ \ "billing").read[Option[CreateAddressRequest]] and
    (__ \ "shipping").read[Option[CreateAddressRequest]] and
    (__ \ "status").read[String] and
    (__ \ "email").read[String] and
    (__ \ "paymentMethod").read[String] and
    (__ \ "paymentTerm").read[Option[String]]
  ).tupled

  val fields13to22: Reads[(Option[String], String, Option[String], Option[String], Option[Set[CreateOrderRequest]], Option[Seq[CreateTransactionOtherChargeRequest]], Option[Seq[CreateNoteRequest]], Option[Seq[String]], Option[String], Option[String])] = (
    (__ \ "deliveryMethod").read[Option[String]] and
    (__ \ "source").read[String] and
    (__ \ "attachments").read[Option[String]] and
    (__ \ "agent").read[Option[String]] and
    (__ \ "orders").read[Option[Set[CreateOrderRequest]]] and
    (__ \ "otherCharges").read[Option[Seq[CreateTransactionOtherChargeRequest]]] and
    (__ \ "notes").read[Option[Seq[CreateNoteRequest]]] and
    (__ \ "subscribers").read[Option[Seq[String]]] and
    (__ \ "trackingId").read[Option[String]] and
    (__ \ "acquisition").read[Option[String]]
  ).tupled

implicit val readsCreateTransactionRequest: Reads[CreateTransactionRequest] = (fields1to12, fields13to22) {
    case((name, balance, amount, currency, dueDate, orderDate, billing, shipping, status, email, paymentMethod, paymentTerm), (deliveryMethod, source, attachments, agent, orders, otherCharges, notes, subscribers, trackingId, acquisition)) => 
    CreateTransactionRequest(name, balance, amount, currency, dueDate, orderDate, billing, shipping, status, email, paymentMethod, paymentTerm, deliveryMethod, source, attachments, agent, orders, otherCharges, notes, subscribers, trackingId, acquisition)
  }

我确信我已经关注并尝试了这个。不幸的是,它不工作而且我仍然有错误

有人可以建议一些其他方法来拆分 Read 上的 22 个字段吗?

虽然没有提供完整的代码,但我可以看出代码中的一些问题。首先,您正在编写以下代码:

(__ \ "billing").read[Option[CreateAddressRequest]]

这里,CreateAddressRequest 不是原始类型。因此,您需要为 CreateAddressRequest.

编写隐式 Writes

然后,您的案例 class 的最大字段是可选的。播放不能手动 serialize/deserialize 可选字段。所以,你需要有下面的代码。

implicit def optionFormat[T: Format]: Format[Option[T]] = new Format[Option[T]] {
    override def reads(json: JsValue): JsResult[Option[T]] = json.validateOpt[T]

    override def writes(o: Option[T]): JsValue = o match {
      case Some(t) => implicitly[Writes[T]].writes(t)
      case None    => JsNull
    }
  }

而且,播放也不能serialize/deserialize日期字段。您还需要写 Writes of Date。下面是java.util.Date写的示例代码。

implicit object DateFormat extends Format[java.util.Date] {
    val format = new java.text.SimpleDateFormat("yyyy-MM-dd")
    def reads(json: JsValue): JsResult[java.util.Date] = JsSuccess(format.parse(json.as[String]))
    def writes(date: java.util.Date): JsString = JsString(format.format(date))
  }

示例已解释 and you can read my article here