无法调用该操作,最终得到一个错误:java.lang.IllegalArgumentException:只有JsObjects可以存储在Play框架中?

时间:2016-03-07 09:47:55

标签: mongodb scala playframework-2.3 reactivemongo play-reactivemongo

我是Reactivemongo数据库(2.6)的新手,因为我正在尝试上传/插入json对象(它是键/值对,我将其发送到我的UI中点击提交按钮后存储在数据库中)我的本地系统使用Play Framework / Scala存储在Mongodb中(尝试使用Play 2.2.3和2.3.8)。我试过了:

import play.api.libs.json.{JsObject, JsValue, OWrites}
import play.api.mvc.{Action, Controller}
import play.modules.reactivemongo.MongoController
import play.modules.reactivemongo.json.collection._

import scala.concurrent.ExecutionContext.Implicits.global

object Application extends Controller with MongoController {
  def jsinfocollection: JSONCollection = db.collection[JSONCollection]("mycollection")

  implicit val jsvalueWrites = new OWrites[JsValue] {
    println("implicit val jsvalueWrites ...")//getting the message on Play console
    override def writes(o: JsValue): JsObject = o match {
      case o : JsObject => o
      case _ => throw new IllegalArgumentException("Only JsObjects can be stored")
    }
  }

  def createJson = Action.async(parse.json) {
    println("createJson calling...")//getting the message on Play console
    request =>
        jsinfocollection.insert(request.body).map{
    println("jsinfocollection.insert...")//getting the message on Play console
        r => Created(s"JsonInfo is Saved with result $r")
      }
  }
}

我在Mongodb中创建了一个集合,如:>db.createCollection("mycollection")

{ "ok" : 1 }

但如果我给:>db.mycollection.count() - 给0,否则如果我给:db.mycollection.find() - 什么都不给

请让我知道如何将我的json数据插入我需要的集合("mycollection")。提前致谢。

我在控制台上收到以下内容:

implicit val jsvalueWrites ...
createJson calling...
jsinfocollection.insert...
[error] play - Cannot invoke the action, eventually got an error: java.lang.IllegalArgumentException: Only JsObjects can be stored

Internal server error, for (POST) [/createJson] 

1 个答案:

答案 0 :(得分:1)

当你使用Action.async(parse.json)时,你在request.body中有一个JsValue

jsinfocollection只能存储JsObjects(JsObjects只有一种类型的JsValues,其他类型是JsArray,JsString,...)

以下代码应该可以满足您的需求

import play.api.libs.json.{JsObject, JsValue, OWrites}
import play.api.mvc.{Action, Controller}
import play.modules.reactivemongo.MongoController
import play.modules.reactivemongo.json.collection._

import scala.concurrent.ExecutionContext.Implicits.global

object Application extends Controller with MongoController {
  def jsinfocollection: JSONCollection = db.collection[JSONCollection]("mycollection")

  implicit val jsvalueWrites = new OWrites[JsValue] {
    override def writes(o: JsValue): JsObject = o match {
      case o : JsObject => o
      case _ => throw new IllegalArgumentException("Only JsObjects can be stored")
    }
  }

  def createJson = Action.async(parse.json) {
    request =>
      jsinfocollection.insert(request.body).map{
        r => Created(s"JsonInfo is Saved with result $r")
      }
  }
}

也许有一种更简单的方法来创建jsvalueWrites No Json serializer as JsObject found for type play.api.libs.json.JsObject 也许更新到最新版本有帮助

注意:验证字符串是有效的JsValue将由parse.json中的框架完成,验证是一个对象在jsvalueWrites中完成,如果你需要完全控制,你可以实现OWrites [ String]并删除parse.json