使用 Play JSON API 将数组读入自定义对象列表的最简单方法
Posted
技术标签:
【中文标题】使用 Play JSON API 将数组读入自定义对象列表的最简单方法【英文标题】:Simplest way to read an array into a list of custom objects with Play JSON API 【发布时间】:2016-01-05 15:41:50 【问题描述】:我正在使用 Play JSON API(最新版本;Play 2.4),将传入的 JSON 读取到对象中。
编写 JSON 时,使用自定义对象列表绝对没有问题,只要我有implicit val writes = Json.writes[CustomType]
。
但显然反之亦然,因为即使为***类型和列表项类型(使用Json.reads[Incoming]
和Json.reads[Item]
)生成了Reads
,以下内容也不起作用。自定义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 =>
【问题讨论】:
【参考方案1】:尝试为Item
定义案例类和对象之前为Incoming
定义案例类和对象。有关更多信息,请参阅此答案:https://***.com/a/15705581
【讨论】:
谢谢,这也有效!因此,这两个答案都独立地解决了问题。我想我会更喜欢这个(而不是import tweak),因为它不太可能再次意外中断(例如,通过在提交时启用“优化导入”)。【参考方案2】:问题可能出在您在 Controller 中的导入中。只需导入“传入”即可导入案例类。为了导入隐式 val,请尝试“Incoming._”。这将导入 Object Incoming 的所有成员。
【讨论】:
哇,你是对的。它开始使用这些导入:import models.Incoming; import models.Incoming._; import models.Item._
到目前为止,我一直信任 IntelliJ IDEA 为我处理和优化导入,但在这种情况下它失败了。
它永远无法知道要使用哪个隐式变量,因为它可能来自许多不同的地方,这总是必须是手动的。以上是关于使用 Play JSON API 将数组读入自定义对象列表的最简单方法的主要内容,如果未能解决你的问题,请参考以下文章
使用 Bluebird 将所有 csv 文件读入节点 js 中的 1 个 JSON 对象数组