Play& ReactiveMongo:如何从控制器中的请求反序列化Json

时间:2014-01-01 18:29:07

标签: json mongodb scala playframework reactivemongo

以下再次是我在previous post中提供的案例类...但是cmbaxter建议的修正:

case class User(
  id: Option[BSONObjectID],
  name: String,
  addresses: Option[List[BSONObjectID]]
)

object User {
  implicit object UserWriter extends BSONDocumentWriter[User] {
    def write(user: User) = BSONDocument(
      "_id" -> user.id.getOrElse(BSONObjectID.generate),
      "name" -> user.name,
      "addresses" -> user.addresses
    ) 
  }

  implicit object UserReader extends BSONDocumentReader[User] {
    def read(doc: BSONDocument) = User(
      doc.getAs[BSONObjectID]("_id"),
      doc.getAs[String]("name").get,
      doc.getAs[List[BSONObjectID]]("addresses")
    )
  }
}

现在我正在尝试实现一个Play控制器来验证传入的Json并将其保存到数据库(MongoDB)中。以下是我的代码:

object Users extends Controller with MongoController {

  private def collection = db.collection[JSONCollection]("users")

  def create = Action.async(parse.json) { request =>
    request.body.validate[User].map { user =>
      collection.insert(user).map { lastError =>
        Logger.debug(s"Successfully inserted with LastError: $lastError")
        Created
      }
    }.getOrElse(Future.successful(BadRequest("invalid json")))
  }
}

上面的代码无法编译,因为编译器找不到任何Json反序列化器:

[error] /home/j3d/Projects/test/app/controllers/Users.scala:44: No Json deserializer found for type models.User. Try to implement an implicit Reads or Format for this type.
[error]     request.body.validate[User].map { user =>
[error]                          ^

是否可以重复使用我在BSONDocumentWriter随播广告对象中定义的BSONDocumentReaderUser,而不是实施ReadsWrites

2 个答案:

答案 0 :(得分:1)

不,您不能将BSON文档读取器/写入器重用为JSON读/写。但是,您可以将JSON读/写重用为BSON文档读取器/写入器。您希望使用JSONCollection从play-reactive-mongo-plugin访问数据库,然后将您的BSON文档读取器/写入器重写为JSON读/写。您可以在play-mongo-knockout激活器模板中看到这样做的示例:

https://github.com/typesafehub/play-mongo-knockout

答案 1 :(得分:1)

如果你还在寻找更复杂的例子,我最后会在3小时后结束。它是模型自动写入的基本实现,它验证json请求并使用10行代码存储到集合中:)您不需要在控制器中重复插入

https://github.com/MilosMosovsky/play-reactivemongo-models