Action(parser.json)与Action.async错误,并使用并发.执行.生成的隐含语句无法在Play S



我正试图创建一个向mongodb插入数据的post请求,使用:1.sbt 0.13.62.播放2.103.标量2.11.24.播放2 reactivamongo 0.10.25.mongodb 2.6.4

通过json发布数据,并为模型创建一个case类,并使用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.ssync时,我的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)

有人能解决我的问题吗?

代码的问题是使用Future回调来操作可变变量。该函数将在Future完成之前很久返回,因此回调基本上不执行任何操作。相反,您应该使用Action.asyncmap——Future到您想要的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做什么)

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

Action vs Action.async

如果你想到的是高级别的动作,它们接受、输入并产生输出,那么这两个动作做的是相同的,但略有不同。这两者都接收请求和输出结果。Action.async允许操作代码正确处理Futures。我跳过了一些细节,但我希望这能有所帮助。

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

相关内容