【问题标题】:Cannot invoke the action, eventually got an error: java.lang.IllegalArgumentException: Only JsObjects can be stored in Play framework?无法调用动作,最终报错:java.lang.IllegalArgumentException: Only JsObjects can be stored in Play framework?
【发布时间】:2016-03-07 09:47:54
【问题描述】:

我是 Reactivemongo 数据库 (2.6) 的新手,因为我正在尝试从我的本地系统使用 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] 

【问题讨论】:

  • 您使用的是相当旧的版本,用于 Play 和 ReactiveMongo。
  • @cchantep,我可以知道任何解决方案,因为我正在使用 Play(2.2.3) 和 Mongo(2.6)。
  • 我怀疑你是否会通过弃用的版本获得很多社区支持
  • @cchantep,好的,我可以在新版本中了解它吗?
  • 您的错误与 Mongo 无关。请阅读有关操作的 Play 文档。

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


【解决方案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

【讨论】:

  • 感谢您的回复,我已经尝试了上面的事情,但是我收到了如下错误:value asJson is not a member of play.api.libs.json.JsValue,我在问题和描述。我正在使用 Play 2.2.3 和 MongoDB 2.6。请告诉我。
  • 对不起。在执行 Action.async(parse.json) 时,request.body 中已经有一个 JsValue。验证将在您的代码之外完成。我会更新我的答案
  • 是的,请务必告诉我。提前致谢。
  • 检查一下就知道了。 @Dhana。
  • 如果您收到此错误是因为您发送的正文不包含 json 对象。
猜你喜欢
  • 2018-07-28
  • 2022-12-02
  • 2023-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-01
相关资源
最近更新 更多