0

我正在尝试使用以下方法创建一个向 mongoddb 插入数据的发布请求: 1. sbt 0.13.6 2. play 2.10 3. scala 2.11.2 4. play2-reactivamongo 0.10.2 5. mongodb 2.6.4

通过json发布数据,并为模型创建案例类,并使用JSPath将json转换为实体类。

这是我的示例代码:

def inserTransaction = Action(parser.json) { implicit request =>

   val json = request.body
   val data = json.as[Transaction]
   Logger.info(data.toString)
   val future = collection.insert(data.copy(id = Option[BSONObjectID](BSONObjectID.generate)))
   var result = ""

   future.onComplete {
     case Failure(t) => result = "An error has occured: " + t.getMessage
     case Success(post) => result = "success"
   }
   Ok(result)
}

我已经看到一些使用 Action.sync 在控制器中处理异步的示例代码,但是当我尝试使用 Action.sync 时,我的 Intellij IDE 检测到错误“无法将 Action.sync 解析为签名”,我试图改变像这样的函数的结果

future.onComplete {
    case Failure(t) => Ok("An error has occured: " + t.getMessage)
    case Success(post) => Ok("success")
  }

所以我决定使用 Action(parser.json) ,但是来自 activator play 的问题是告诉我应该在我的代码中使用“import play.api.libs.concurrent.Execution.Implicits._”。但是当我导入库时,出现了一个新错误:

 ! Internal server error, for (POST) [/insertdata] ->

java.lang.ExceptionInInitializerError: null ....

Caused by: play.api.PlayException: ReactiveMongoPlugin Error[The ReactiveMongoPlugin has not been         
initialized! Please edit your conf/play.plugins file and add the following line....

当我尝试重新加载请求时,它显示了另一个错误:

! Internal server error, for (POST) [/api/insertdata] ->

java.lang.NoClassDefFoundError: Could not initialize class controllers.TransactionController$

[error] application - Error while rendering default error page
scala.MatchError: java.lang.NoClassDefFoundError: Could not initialize class 
controllers.TransactionController$ (of class java.lang.NoClassDefFoundError)

有人对我的问题有任何解决方案吗?

4

2 回答 2

5

您的代码的问题是您正在使用Future回调来操作可变变量。该函数将在Future完成之前很久就返回,因此回调基本上什么都不做。相反,您应该使用Action.asyncandmapFuture您想要的Result. 您还可以使用它recover来处理任何故障。

您的代码应该看起来更像这样:

def inserTransaction = Action(parser.json).async { implicit request =>
   val json = request.body
   val data = json.as[Transaction]
   Logger.info(data.toString)
   val future = collection.insert(data.copy(id = Option[BSONObjectID](BSONObjectID.generate)))

   future.map(result => Ok(result))
       .recover { t: Throwable => Ok("An error has occured: " + t.getMessage) }
}

甚至更好:

def inserTransaction = Action(parser.json).async { implicit request =>
   request.body.validate[Transaction].fold(
       error => Future.successful(Ok("json errors...")),
       data => {
           collection.insert(data.copy(id = Option[BSONObjectID](BSONObjectID.generate)))
              .map(result => Ok(result))
              .recover { t: Throwable => Ok("An error has occured: " + t.getMessage) }
       }
   )
}

(可能无法立即编译,因为我不知道是什么collection.insert

于 2014-10-21T13:23:30.147 回答
0

这个问题可能会有所帮助:在 Play Framework 2.2 中使用非异步操作有什么好处吗?

Action vs Action.async

如果您考虑采取和输入并产生输出的高级操作,那么这两者做同样的事情但略有不同。这两个都接受请求和输出结果。Action.async 允许操作代码正确处理 Futures。我跳过了一些细节,但我希望这会有所帮助。

你能粘贴你的插件文件吗?

于 2014-10-21T12:01:10.553 回答