无法将play.api.libs.json.JsLookupResult的实例写入HTTP响应。尝试定义Writable [play.api.libs.json.JsLookupResult]

时间:2016-02-04 05:13:45

标签: json mongodb scala playframework sbt

我正在将Play Framework服务器从2.2.2升级到2.4.4,因为我的应用程序在旧版本中工作正常,但在升级时会出现各种错误,如:

border-style: solid

build.sbt:

 Cannot write an instance of play.api.libs.json.JsLookupResult to HTTP response. Try to define a Writable[play.api.libs.json.JsLookupResult]
    Ok<gts<0>>
      ^

app.scala:

name := """TestApp"""

version := "1.0-SNAPSHOT"

lazy val root = (project in file(".")).enablePlugins(PlayJava)

//scalaVersion := "2.11.6"
//scalaVersion := "2.10.2"

libraryDependencies ++= Seq(
  javaJdbc,
  cache,
  javaWs,
  jdbc,
  cache,
  "com.typesafe.play" %% "anorm" % "2.4.0",
  "com.google.inject" % "guice" % "4.0",
  "javax.inject" % "javax.inject" % "1",
  "org.reactivemongo" %% "reactivemongo" % "0.10.0",
  "org.reactivemongo" %% "play2-reactivemongo" % "0.10.2",
  "org.mockito" % "mockito-core" % "1.9.5" % "test",
  "org.webjars" % "requirejs" % "2.1.1",
  "org.postgresql" % "postgresql" % "9.4-1200-jdbc41",
  "postgresql" % "postgresql" % "9.1-901.jdbc4",
  "com.typesafe.play" % "play-iteratees_2.10" % "2.2.3",
  "com.typesafe.slick" % "slick_2.10" % "2.1.0",
  "com.typesafe.play" % "play-jdbc_2.10" % "2.4.4",
  "org.apache.flume" % "flume-ng-core" % "1.5.2",
  "org.apache.flume" % "flume-ng-sdk" % "1.5.2",
  "org.scala-lang" % "scala-compiler" % "2.11.6"
)

请告诉我在哪里出错,无论是在我的控制器类还是build.sbt中?提前致谢。

1 个答案:

答案 0 :(得分:1)

JsArray编制索引不会返回该索引处的JsValue,而是返回JsLookupResult JsDefinedJsUndefined(如果,例如,索引超出范围。)我认为这在Play 2.3中发生了变化。

虽然您可以通过Play提供的默认JSON可编写方式将JsValue直接写入HTTP响应,但JsLookupResult没有这样的可写内容。您可以通过JsLookupResult上的模式匹配来修复它,以提取值,并处理它的缺席:

futurePersonsJsonArray.map { dao =>
  dao(0).match {
    case JsDefined(js) => Ok(js)
    case _ => NotFound
  }
}

或使用toOption获取Option[JsValue]

futurePersonsJsonArray.map { dao =>
  dao(0).toOption.map(js => Ok(js)).getOrElse(NotFound)
}

但是,修复代码的更好方法是直接在Json.toJson()的已兑换结果上使用futureUserList,而不是将其放在JSON数组中,然后立即再拿出来:

def index = Action.async {
  val cursor: Cursor[JsValue] = collection.
    find(Json.obj()).
    cursor[JsValue]
  val futureUsersList: Future[List[JsValue]] = cursor.collect[List]()

  futureUsersList.map { list =>
    Ok(Json.toJson(list))
  }
}