2016-01-21 54 views
0

在使用reactivemongo向mongoDB写入文档的db对象中,我有以下功能。在发送成功的JSON响应之前等待数据库事务结果

def writeDocument(json: JsValue):Future[WriteResult] = { 

    def collection: JSONCollection = { 
    val driver = new MongoDriver 
    val connection = driver.connection(List("localhost")) 
    val db = connection("superman") 
    db.collection[JSONCollection]("Powers") 
    } 

val document = json.as[JsObject] 
val future = collection.insert(document) 
future.onComplete { 
    case Failure(e) => { 
    logger.error("""Message="Database is not reachable." """ + """ transactionID=""" + (json \\ "transactionID") + " errorResponse=" + e.getLocalizedMessage) 
    throw e} 
    case Success(result) => 
    println("successfully inserted document with result = " + result) 
} 
future 
} 

在控制器侧,我有它调用上述writeDocument()功能这部分代码。由于reactivemongo是异步的,所以即使数据库不存活,我也总是会获得成功的JSON消息。我知道数据库写入正在通过Futures进行,我如何才能确保只有在数据成功写入数据库后才能发送成功的响应?

def validateRequest(json: JsValue): Result = { 

{ 
    val logger = LoggerFactory.getLogger("superman") 
    val jsonSchema = Source.fromURL(getClass.getResource("/schema.json")).getLines.mkString 
    val transactionID = (json \ "transactionID").get 
    val result: VA[JsValue] = SchemaValidator.validate(Json.fromJson[SchemaType](
    Json.parse(jsonSchema.stripMargin)).get, json) 

    result.fold(
    invalid = { errors => 

     var violatesList = List[String]() 
     val invalidError = Json.obj("transactionID" -> transactionID, "status" -> "error", "description" -> "Invalid Request Received") 
     for (msg <- (errors.toJson \\ "msgs")) { 
     violatesList = (msg(0).get).as[String] :: violatesList 
     } 
     val errorResponse = Json.toJson(invalidError ++ Json.obj("violations" -> violatesList)) 
     logger.error("""Message="Invalid Request Received" for transactionID=""" + transactionID.toString() + "errorResponse:" + errorResponse) 
     BadRequest(errorResponse) 

    }, 

    valid = { 
     post => 
     val insertResult = db.writeDocument(json) 
     insertResult.map{ result => 
      val json = Json.obj("transactionID" -> transactionID.toString, 
      "status" -> "OK", "message" -> ("Valid Request Received")) 
      Ok(json) 
     }.recover{ case error: Throwable => 
      val json = Json.obj("transactionID" -> transactionID.toString, 
      "status" -> "FAILED") 
      Ok(json) 
     } 




) 
} 

}

回答

1

你需要做以下修改:

1.At的writeDocument,而不是末端(或除为了直接处理未来,你应该回报未来。

2.In控制器,你应该对未来映射到一个响应,通过写这样的:当我尝试返回`future`并添加返回类型

def myAction() = Action.async { request => 
    insertResult.map{ result => 
    val json = Json.obj("transactionID" -> transactionID.toString, 
         "status" -> "OK", "message" -> ("Valid Request Received")) 
    Ok(json) 
    }.recover{ case error: Throwable => 
    val json = Json.obj("transactionID" -> transactionID.toString, 
         "status" -> "FAILED") 
    Ok(json) 
    } 
} 
+0

上得到错误'Expression of type Future [Result]与预期的类型_X不一致'请参阅我的Edit 1.我得到'Expression of键入Future [结果]不符合期望的类型_X' – summerNight

+0

@summerNight您是否已更新writeDocument()方法以最终返回未来?你能否更新你的问题中的writeDocument()方法来反映? –

+0

我更新了它,并在控制器端添加了该功能的其余部分 – summerNight

1

简单地把未来和其映射到想要Result

比赛将尽快承诺被赎回达到这个结果:Play Async

def writeDocument(json: JsValue): Future[LastError] = { 
    // ... 
    future 
} 


valid = { post => 
    val future = db.writeDocument(json) 
    future.map { _ => 
    val successResponse = Json.obj("transactionID" -> transactionID.toString, "status" -> "OK", "message" -> ("Valid Request Received")) 
    Ok(successResponse) 
    } 
} 
+0

'未来[LastError]'时, IDE抱怨'表达式'Future [WriteResult]'不符合期望的类型'Future [LastError]' – summerNight

+0

根据http://reactivemongo.org/releases/0.11/documentation/tutorial/write-documents.html :以前由写入操作返回的类型Future [LastError]被新API中的Future [WriteResult]所取代。当我尝试从'writeDocument'返回'Future [WriteResult]'时,我在控制器 – summerNight

相关问题