使用Play 2.1.1在JSON中迭代数组
我正在使用play 2.1.1,在遍历数组时遇到问题。我曾在某个地方读到,您可以为列表[对象]创建读取,但每次尝试这样做时,我都会收到一个错误,即“找不到unapply函数”,该行显示使用Play 2.1.1在JSON中迭代数组,json,scala,playframework,playframework-2.0,playframework-json,Json,Scala,Playframework,Playframework 2.0,Playframework Json,我正在使用play 2.1.1,在遍历数组时遇到问题。我曾在某个地方读到,您可以为列表[对象]创建读取,但每次尝试这样做时,我都会收到一个错误,即“找不到unapply函数”,该行显示 implicit val userListReads:Reads[List[FBUser]]=Json.Reads[List[FBUser]]”。问题是“=Json.Reads[List[FBUser]] 我不知道还能尝试什么。如蒙协助,将不胜感激 def linkUsers() = Action { impli
implicit val userListReads:Reads[List[FBUser]]=Json.Reads[List[FBUser]]”。问题是“=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]]
}
您的
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
目的
即使@martin的答案给出了关于json消息和预期结果之间不匹配的直接解决方案,我还是想给您一些建议,以一种干净的方式实现您的目标
这是因为,阿菲克,你重新定义了太多的东西,你可能会遇到错误没有报告的情况。。。但是被一个不同的错误隐藏了,比如NoTouchElementException
最后,我想给出一个保持消息不变的解决方案(比如第二个@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将解析为隐式和通用的读取
和OWrites
最后是Application.scala
,它将只包含与某些用例相关的代码,比如包含数据
字段的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))
}
}
}
在该控制器中,我们可以看到它为初始情况定义了特定的读取
,因此,由于使用了验证
、映射
和恢复总计
,因此对数据字段的访问和对FBUser
实例的读取是安全的
一些词
关于安全性的最后一个注释,<代码> JSON.PARSE 是不安全的,所以为了更安全,你应该根据你的工作流程考虑一些选项,其中一些是: *使用json主体解析器可以显式处理错误的json格式 *使用控制器中为此特定案例定义的专用案例类(然后使用类似于
FBUser
的初始概念定义其读取/…)