我正在尝试使用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)
}
答案 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
。