5

解析後に Json 配列を操作するのに問題があります。

post メソッドを使用して Javascript で次の Json オブジェクトを渡します: [{"id":"someid"},{"id":"anotherid"}]

私は Andy のセットアップ ( Play 2.1.1 で JSON の配列を反復処理する) を使用して、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 はオブジェクト controllers.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)         
  }

これが他の人に役立つことを願っています:)

4

1 に答える 1

0

既にお気づきのように、map を 2 回使用する必要がありました。1 回目は JsResult のコンテンツにアクセスし、もう 1 回はその JsResult 内の List のコンテンツにアクセスします。このようにして、探していたネストされた ID にアクセスし、実行可能な解決策を見つけました。

ただし、変更可能な状態に依存せずに問題を解決する、かなりエレガントなソリューションを指摘したいと思います。

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

検証を 2 つの考えられるケースに一致させます。合格して ID のリストとともに 200 を返すか、失敗してエラーとともに 400 を返します。

于 2015-04-19T17:20:09.603 に答える