Action(parser.json) vs Action.async Error и использование concurrent.Execution.Implicits не может инициализировать контроллеры классов в Play Scala

Я пытаюсь создать почтовый запрос на вставку данных в mongoddb, используя: 1. sbt 0.13.6 2. play 2.10 3. scala 2.11.2 4. play2-реактивамонго 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), но проблема, возникшая в результате активации активатора, заключается в том, что я должен использовать "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)

У кого-нибудь есть решение моей проблемы?

2 ответа

Решение

Этот вопрос может помочь: есть ли преимущества в использовании не асинхронных действий в Play Framework 2.2?

Действие против Действие.async

Если вы думаете о действиях на высоком уровне, которые берут и вводят, и производят выход, то эти два делают то же самое, но немного отличаются. Оба из них принимают в запросе и выводят результаты. Action.async позволяет коду действий правильно обращаться с фьючерсами. Я пропускаю некоторые детали, но надеюсь, что это поможет.

Можете ли вы вставить свой файл плагинов?

Проблема с вашим кодом в том, что вы используете Future обратный вызов для управления изменяемой переменной. Функция вернется задолго до Future завершен, поэтому обратный вызов по существу ничего не делает. Вместо этого вы должны использовать Action.async а также map 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 делает)

Другие вопросы по тегам