3

我的 Scala Play 项目中有一个控制器方法,它以 JSON 作为输入。我想将此 JSON 转换为我拥有的模型对象。

这是我的控制器方法:

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 很陌生,所以我可能在这里忽略了一些非常简单的东西。

4

1 回答 1

2

而不是 using 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"))
  })
}

现在,我猜这会告诉你“2013 年 5 月 15 日”不是有效日期。Play 中 JSON 的默认日期格式是yyyy-MM-dd. 您可以通过修改格式来指定自定义格式:

...
(__ \ "datePosted").format[Date](Format(Reads.dateReads("MM-dd-yyyy"), Writes.dateWrites("MM-dd-yyyy"))) and
...

另一种内置的Reads.IsoDateReads,这比美国唯一的月日年格式更标准,另一种完全避免这个问题的方法是使用 Long as milliseconds since epoch。

于 2013-11-07T23:33:37.800 回答