类型不匹配;发现:scala.collection.immutable.Stream[String] 需要:Play Scala 中的字符串?

type mismatch; found : scala.collection.immutable.Stream[String] required: String in Play Scala?

我正在尝试使用 Play(2.2.x) 的 scala/anorm 显示来自数据库的 json 数据,如果我进行以下试验,我会收到如下错误: type mismatch; found : scala.collection.immutable.Stream[String] required: String,但如果我这样写:sql().map(row => rowString).toString - 给出 Stream 类型 json 数据(我不需要它),所以我怎样才能得到它的正常 json 数据?请帮助我并提前致谢。

控制器:

class Test extends Controller {
    def getTest = Action { 
    var sql: SqlQuery = SQL("select name::TEXT from test");
    def values: String =  DB.withConnection { implicit connection => 
    sql().map(row => row[String]("name"))//giving error: type mismatch; found : scala.collection.immutable.Stream[String] required: String
    }
    Ok(values)
    }

您似乎正在使用 Anorm 进行数据库访问。如上面的评论所述,执行 Anorm 查询 return 是一个 Stream 而不仅仅是一个值。当您映射值时,它再次 returning Stream of String 以便结果可以作为流处理。这对于大型结果集非常有用,在这种情况下,增量处理流并将结果流式传输到客户端更有意义。看起来你才刚刚开始,所以你现在可能不想担心这个。

您只需使用 toList:

即可将流中的结果转换为常规列表
val resList = sql().map(row => row[String]("name")).toList

现在,您还需要取消转义字符串并将其 return 作为 JSON 结果。这可以通过使用字符串插值来完成。为此,您只需将 String 包围在 StringContext 中,然后不带参数调用 s 方法。

val newResList = resList.map(s => StringContext(s).s())

最后,您实际上应该将 String 转换为 PlayJson JsValue 类型,以便您的控制器实际上 return 是正确的类型。

Json.parse(newResList.mkString("[",",","]")

mkString方法用于将列表转换为有效的JSON字符串。您需要 import play.api.libs.json.Json 才能正常工作。将 JsValue 传递给 Ok 可确保将响应的 MIME 类型设置为 "application/json"。您可以通过播放 here 了解有关使用 JSON 的更多信息。如果您打算构建 JSON 服务,这将很重要。

将它们放在一起,你会得到以下内容:

class Test extends Controller {
  def getTest = Action { 
    var sql: SqlQuery = SQL("select name::TEXT from test");
    def values: JsValue =  DB.withConnection { implicit connection => 
      val resList = sql().map(row => row[String]("name")).toList 
      val newResList = resList.map(s => StringContext(s).s())
      Json.parse(newResList.mkString("[",",","]")
  }
  Ok(values)
}

您还可以使用以下替代结构来简化和摆脱相当草率的 mkString 调用。

class Test extends Controller {
  def getTest = Action { 
    var sql: SqlQuery = SQL("select name::TEXT from test");
    def values: JsValue =  DB.withConnection { implicit connection => 
      val resList = sql().map(row => row[String]("name")).toList 
      Json.toJson(resList.map(s => Json.parse(StringContext(s).s())))
  }
  Ok(values)
}

这会解析列表中的每个 JSON 字符串,然后使用 Play 内置的 JSON 库的功能再次将列表转换为 JsArray