我的 Scala Play 项目中有一个将 JSON 作为输入的 Controller 方法。我想将此 JSON 转换为我拥有的模型对象。
这是我的 Controller 方法:
def broadcastPost = Action(parse.json) { request =>
(request.body).asOpt[Post].map { post =>
Post.create(post.channelId, post.message, post.datePosted, post.author)
Ok(play.api.libs.json.Json.toJson(
Map("status" -> "OK", "message" -> ("Post created"))
))
}.getOrElse {
BadRequest(play.api.libs.json.Json.toJson(
Map("status" -> "Error", "message" -> ("Missing parameter [Post]"))
))
}
}
这是模型:
case class Post(id: Pk[Long], channelId: Long, message: String, datePosted: Date, author: String)
及其隐式格式化程序:
implicit val postFormat = (
(__ \ "id").formatNullable[Long] and
(__ \ "channelId").format[Long] and
(__ \ "message").format[String] and
(__ \ "datePosted").format[Date] and
(__ \ "author").format[String]
)((id, channelId, message, datePosted, author) => Post(id.map(Id(_)).getOrElse(NotAssigned), channelId, message, datePosted, author),
(p: Post) => (p.id.toOption, p.channelId, p.message, p.datePosted, p.author))
当我使用以下数据向该方法发送 POST 请求时:
{"channelId":1, "message":"Wanna get a game in?", "dateCreated":"5-15-2013", "author":"Eliot Fowler"}
我得到以下响应:
{"status":"Error","message":"Missing parameter [Post]"}
我是 Scala 的新手,所以我可能忽略了一些非常简单的东西。
最佳答案
不要使用丢失错误的asOpt
,而应使用validate
,这将允许您返回错误消息,然后查看问题所在,例如:
def broadcastPost = Action(parse.json) { request =>
request.body.validate[Post].fold({ errors =>
BadRequest(Json.obj(
"status" -> "Error",
"message" -> "Bad JSON",
"details" -> JsError.toFlatJson(errors)
))
}, { post =>
Post.create(post.channelId, post.message, post.datePosted, post.author)
Ok(Json.obj("status" -> "OK", "message" -> "Post created"))
})
}
现在,我猜它会告诉您“5-15-2013”不是有效日期。 Play 中 JSON 的默认日期格式是 yyyy-MM-dd
。您可以通过修改格式来指定自定义格式:
...
(__ \ "datePosted").format[Date](Format(Reads.dateReads("MM-dd-yyyy"), Writes.dateWrites("MM-dd-yyyy"))) and
...
另一个内置 Reads.IsoDateReads
,这比美国唯一的月日年格式更标准,另一种完全避免此问题的方法是使用 Long as 自纪元以来的毫秒数。
关于json - 来自 JSON 请求的 Scala 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19844092/