类型不匹配; found:scala.collection.immutable.Stream [String] required:Play Scala中的字符串?

时间:2016-03-02 05:05:41

标签: json scala scala-collections anorm

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

contorller:

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)
    }

1 个答案:

答案 0 :(得分:1)

看起来您正在使用Anorm进行数据库访问。如上面的注释中所述,执行Anorm查询会返回Stream而不是仅返回值。映射该值时,它会再次返回Stream String,以便将结果作为流处理。这对于大型结果集非常有用,其中以递增方式处理流并将结果流式传输到客户端更有意义。看起来你刚刚开始,所以你现在可能不想担心这一点。

只需使用toList

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

现在,您还需要取消对字符串的转换并将其作为JSON结果返回。这可以通过使用字符串插值来完成。要执行此操作,您只需将String中的StringContext括起来,并调用s方法,不带任何参数。

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

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

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