我正在使用play 2.1.1并且我在迭代数组时遇到问题。我曾在某处读过你可以为List [Object]创建一个读取,但是每当我尝试这样做时,我都会收到错误"No unapply function found"
的行
implicit val userListReads: Reads[List[FBUser]] = Json.reads[List[FBUser]]". The issue is " = Json.reads[List[FBUser]]
我无法尝试其他什么。非常感谢任何帮助。
def linkUsers() = Action { implicit request =>
val json = Json.parse("{\"data\": [{\"name\": \"Me Lazyan\",\"id\": \"1182\"},{\"name\": \"Chales Dselle\",\"id\": \"10115\"},{\"name\": \"Be My\",\"id\": \"10275\"},{\"name\": \"De Rwani\", \"id\": \"11189\"},{\"name\": \"Phoe Johon\", \"id\": \"11372\"}]}")
val peoples = json.validate[List[FBUser]].get
peoples.foreach(println)
Ok(json).withHeaders(CONTENT_TYPE -> "text/json")
}
case class FBUser(
name: String,
id: String
)
object FBUser {
/** Uses a Scala Macro to define the Reads function */
implicit val userReads: Reads[FBUser] = Json.reads[FBUser]
implicit val userListReads: Reads[List[FBUser]] = Json.reads[List[FBUser]]
}
答案 0 :(得分:13)
即使@ martin的回答是关于json消息与预期结果之间不匹配的直接解决方案,我也想给你一些建议,以便找到一个干净的方法来实现你的目标。
那是因为,AFAICK,你正在重新定义太多的东西,你可以遇到没有报告错误的情况......但只是被NoSuchElementException等不同的错误隐藏。
最后,我想提供一个解决方案,让你的信息保持不变(就像第二个@Martin的解决方案一样)。
我们的想法是将事务打包,并将代码分为三个不同的文件:
FBUser.scala
简单地声明了模型结构
package models
case class FBUser(
name: String,
id: String
)
formats.scala
这是一个收集所有格式定义的包,特别是json:
package models
import play.api.libs.json._
import play.api.libs.json.Reads._
import play.api.libs.json.util._
import play.api.libs.json.Json._
import play.api.libs.functional.syntax._
package formats {
object jsons {
implicit val fbUserFormat:Format[FBUser] = Json.format[FBUser]
}
}
请注意,未提供List[FBUser]
的格式,因为json api将解析为隐式Reads
和OWrites
。
最后,Application.scala
将包含仅与某些用例相关的代码,例如包含data
字段的json对象,FBUser
列表。
package controllers
import play.api._
import play.api.mvc._
import play.api.libs.json._
import play.api.libs.json.Json._
import models._
object Application extends Controller {
import models.formats.jsons._
val readUserFromInput = (__ \ 'data).read[List[FBUser]]
def index = Action {
val jsonString = "{\"data\": [{\"name\": \"Me Lazyan\",\"id\": \"1182\"},{\"name\": \"Chales Dselle\",\"id\": \"10115\"},{\"name\": \"Be My\",\"id\": \"10275\"},{\"name\": \"De Rwani\", \"id\": \"11189\"},{\"name\": \"Phoe Johon\", \"id\": \"11372\"}]}"
val json = Json.parse(jsonString)
val users = json.validate(readUserFromInput)
users.map(
list => Ok(Json.toJson(list)) // or Ok(json) to match exactly you example
).recoverTotal{
err => BadRequest(JsError.toFlatJson(err))
}
}
}
在此控制器中,我们可以看到它为初始案例定义了特定的Reads
,因此,由于使用{FBUser
实例,对数据字段和validate
实例的读取的访问是安全的{1}},map
和recoverTotal
。
关于安全的最后一点,Json.parse
是不安全的,所以为了更加安全,你应该考虑一些选项,具体取决于你的工作流程,其中一些是:
*使用json body解析器,它可以让你明确地处理坏的json格式
*使用控制器中为此特定情况定义的专用案例类(然后使用像FBUser
这样的初始定义其读取/ ...)
答案 1 :(得分:12)
您的json
值是一个包含数组的字段data
的对象。您正在尝试将单个对象解析为数组。您可能需要将json
更改为。
val json = Json.parse("[{\"name\": \"Me Lazyan\",\"id\": \"1182\"},{\"name\": \"Chales Dselle\",\"id\": \"10115\"},{\"name\": \"Be My\",\"id\": \"10275\"},{\"name\": \"De Rwani\", \"id\": \"11189\"},{\"name\": \"Phoe Johon\", \"id\": \"11372\"}]")
或将您的代码更改为
val people = (json \ "data").validate[List[FBUser]].get