使用Play JSON API将数组读入自定义对象列表的最简单方法

时间:2016-01-05 15:41:51

标签: json scala playframework playframework-2.4

我正在使用Play JSON API(最新版本; Play 2.4),将传入的JSON读入对象。

JSON时,使用自定义对象列表绝对没问题,只要我有implicit val writes = Json.writes[CustomType]

但显然反之亦然,因为即使为顶级类型和列表项类型生成Reads(使用Json.reads[Incoming]Json.reads[Item]),以下操作也不起作用。自定义Reads实施是强制性的吗?还是我错过了一些明显的东西?使这项工作最简单的方法是什么?

简化示例:

JSON:

{
  "test": "...",
  "items": [
     { "id": 44, "time": "2015-11-20T11:04:03.544" },
     { "id": 45, "time": "2015-11-20T11:10:10.101" }
  ]
}

匹配传入数据的模型/ DTO:

import play.api.libs.json.Json

case class Incoming(test: String, items: List[Item])

object Incoming {
  implicit val reads = Json.reads[Incoming]
}


case class Item(id: Long, time: String)

object Item {
  implicit val reads = Json.reads[Item]
}

控制器:

def test() = Action(parse.json) { request =>
  request.body.validate[Incoming].map(incoming => {
     // ... handle valid incoming data ...
  }).getOrElse(BadRequest)
}

编译器有这样说:

No implicit format for List[models.Item] available.
[error]   implicit val reads = Json.reads[Incoming]
                       ^
No Json deserializer found for type models.Incoming. 
Try to implement an implicit Reads or Format for this type.
[error]     request.body.validate[Incoming].map(incoming => {

2 个答案:

答案 0 :(得分:3)

尝试在Item 之前为Incoming 定义案例类和对象。有关详细信息,请参阅此答案:https://stackoverflow.com/a/15705581

答案 1 :(得分:1)

问题可能出在Controller中的导入中。只需导入“Incoming”即可导入案例类。为了导入隐式val,请尝试“Incoming._”。这将导入Object Incoming的所有成员。