我有JSON结构:
{
"date": "2015-01-01",
"id": 100,
"movies":[
{
"id": 1,
"length": 131,
"timestamp": 1447837200
},
{
"id": 2,
"length": 131,
"timestamp": 1447840800
}
]
}
我需要一些验证: - "日期"是一个有效的日期; - " id" - 是目前名单中的一个数字; - "电影" - 是一个对象列表;
转型: - "时间戳" - 将unixtimestamp解析为Date字符串(HH:mm)
我需要把"日期"和" id"从root到每个数组元素
所以,结果对象:
[
{
"id": 1,
"length": 131,
"timestamp": "09:00",
"parent_id": 100,
"date": "2015-01-01"
},
{
"id": 2,
"length": 131,
"timestamp": "10:00",
"parent_id": 100,
"date": "2015-01-01"
}
]
我写了一些代码,巫婆转换时间戳,但它看起来很糟糕......
val inputJson = play.api.libs.json.Json.parse(
"""{
"date": "2015-01-01",
"id": 100,
"movies":[
{
"id": 1,
"length": 131,
"timestamp": 1447837200
},
{
"id": 2,
"length": 131,
"timestamp": 1447840800
}
]
}"""
)
val timestampTransform = (
( __ \ "timestamp").json.update(
__.read[JsNumber].map(
timestamp => {
JsString(new DateTime(timestamp.asOpt[Int].getOrElse(0)).toString("HH:mm"))
} )
))
val reads = ( __ \ 'movies).json.update(
__.read[JsArray].map(
movies => {
val result = movies.as[List[JsObject]].map(
element => {
element.transform(timestampTransform).get
})
Json.toJson(result)
}
)
)
println(inputJson.transform(reads))
答案 0 :(得分:1)
这是另一种可怕的改造方式。
适用于< = play 2.3.x
import play.api.libs.json._
import org.joda.time.DateTime
case class Movie(id: Int, date: String, parent_id: Int, length: Int, timestamp: String)
implicit val mWritess = Json.writes[Movie]
implicit val nreads = new Reads[JsValue] {
def reads(json: JsValue): JsResult[JsValue] = json match {
case JsObject(Seq(("date", JsString(date)), ("id", pid: JsNumber), ("movies", JsArray(movies)))) => {
movies match {
case s: scala.collection.mutable.ListBuffer[_] => {
val collectedId: Seq[Movie] = s.collect {
case JsObject(Seq(("id", mid: JsNumber), ("length", length: JsNumber), ("timestamp", timestamp: JsNumber))) => {
Movie(mid.asOpt[Int].getOrElse(0), date, pid.asOpt[Int].getOrElse(0), length.asOpt[Int].getOrElse(0),
new DateTime(timestamp.asOpt[Int].getOrElse(0)).toString("HH:mm"))
}
}
JsSuccess(Json.toJson(collectedId))
}
case _ => JsError(s"Error '$date', $pid, $movies")
}
}
case _ => JsError("Invalid format")
}
}
println(inputJson.transform(nreads))
适用于播放2.4.x
case class Movie(id: Int, date: String, parent_id: Int, length: Int, timestamp: String)
implicit val mWritess = Json.writes[Movie]
implicit val nreads = new Reads[JsValue] {
def reads(json: JsValue): JsResult[JsValue] = json match {
case values: JsObject => {
values.fields match {
case Seq(("date", JsString(date)), ("id", pid: JsNumber), ("movies", JsArray(movies))) =>
movies match {
case s: scala.collection.mutable.ListBuffer[_] => {
val collectedId: Seq[Movie] = s.collect {
case movies: JsObject => {
movies.fields match {
case Seq(("id", mid: JsNumber), ("length", length: JsNumber), ("timestamp", timestamp: JsNumber)) =>
Movie(mid.asOpt[Int].getOrElse(0), date, pid.asOpt[Int].getOrElse(0), length.asOpt[Int].getOrElse(0),
new DateTime(timestamp.asOpt[Int].getOrElse(0)).toString("HH:mm"))
}
}
}
JsSuccess(Json.toJson(collectedId))
}
case _ => JsError(s"Error '$date', $pid, $movies")
}
}
}
case _ => JsError("Invalid format")
}
}
println(inputJson.transform(nreads))