【问题标题】:Iterating and reformatting an array in JSON with Play 2.1.1使用 Play 2.1.1 迭代和重新格式化 JSON 中的数组
【发布时间】:2013-07-29 08:37:59
【问题描述】:

解析 Json 数组后,我无法操作它。

我使用 post 方法在 Javascript 中传递以下 Json 对象:[{"id":"someid"},{"id":"anotherid"}]

我使用了 Andy 的设置 (Iterating over an array in JSON with Play 2.1.1) 来解析使用 post 方法传递的 json 编码数组(为了方便,我将代码移到了控制器中)

  case class FBUser(
     id: String
  ){}
  object FBUser {
    /** Uses a Scala Macro to define the Reads function */
    implicit val userReads: Reads[FBUser] = Json.reads[FBUser]
    implicit val fbUserFormat:Format[FBUser] = Json.format[FBUser]
  }

  def doQuery = Action (parse.json){ implicit request =>

    val readIDFromInput =  (__).read[List[FBUser]]

    val IDs = request.body.validate(readIDFromInput)

    IDs.map(
      item => Ok(Json.toJson(item))
    ).recoverTotal{
      err => BadRequest(JsError.toFlatJson(err))
    }

  }

这可以正常工作:它读取并返回 Json 对象。我无法使用 Json 对象创建新变量。在这种情况下,我想构造一个像 {["someid", "anotherid"]} 的 Json 对象(即没有 "id")

首先我尝试了:item => Ok(Json.toJson(item.id)) // trying to access item.id

但这导致了一个错误:值 id 不是对象控制器的成员。ScalaPoster.FBUser

我尝试向对象添加一个函数(def getId():String = { return this.id })。访问该 (item.getId()) 会导致相同的错误。

非常感谢所有帮助!

编辑(没有足够的声誉来回答我自己的问题):

添加另一个映射函数 (Json.toJson(list.map{ item => item.id }) 可以访问 id:

 case class FBUser(
     id: String
  )
  implicit val fbUserFormat:Format[FBUser] = Json.format[FBUser]

  def doQuery = Action (parse.json){ implicit request =>

    var idsValid = true
    var badReq = Json.obj();

      val readIDFromInput =  (__).read[List[FBUser]]

      val listIDs = request.body.validate(readIDFromInput).map {

        case list => Json.toJson(list.map{ item => item.id } )
      }.recoverTotal{
        e => {
          idsValid = false
          badReq = JsError.toFlatJson(e)  
          Json.arr() // empty array                                                                                          
        }
      }                                                                                                                                                                                                                      

    if( idsValid )
      Ok(listIDs)                                                                                                                                                                                                                         
    else                                                                                                                                                                                                                                    
      BadRequest("Detected error:"+ badReq)         
  }

希望这可以帮助其他人:)

【问题讨论】:

    标签: json scala playframework playframework-2.0


    【解决方案1】:

    正如您已经注意到的,您必须使用两次 map:第一次访问 JsResult 的内容,再一次访问该 JsResult 内的 List 的内容。这样,您就可以访问您正在寻找的嵌套 ID,并提出了一个可行的解决方案。

    但是,我想指出一个相当优雅的解决方案,它可以在不依赖可变状态的情况下解决您的问题:

    request.body.validate(readIDFromInput) match {
      case JsSuccess(users, _) => Ok(users.map(_.id))
      case JsError(errors) => BadRequest(errors)
    }
    

    我将验证与它的两种可能情况相匹配:它通过并且我返回 200 和 id 列表,或者它失败并且我返回 400 和错误。

    【讨论】:

      猜你喜欢
      • 2013-04-20
      • 1970-01-01
      • 2021-12-18
      • 1970-01-01
      • 2018-10-27
      • 2021-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多