使用Play 2.1.1在JSON中迭代数组

使用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

我正在使用play 2.1.1,在遍历数组时遇到问题。我曾在某个地方读到,您可以为列表[对象]创建读取,但每次尝试这样做时,我都会收到一个错误,即“找不到unapply函数”,该行显示

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
的初始概念定义其读取/…)