2

Web アプリケーションを Play 2.0.4 から Play 2.1-RC2 に移行しようとしています。

次のような不明なキー ( key1key2)のリストを含む JSON データがあります。

{description: "Blah",
 tags: [
   key1: ["value1", "value2"],
   key2: ["value3"]
 ]
}

JSON からのデータをメタタグのリストに保存したいと考えています。Play 2.0.4 では、次のようなものを使用してtags-listを読み取りました。

def readMetatags(meta: JsObject): List[Metatag] =
  meta.keys.toList.map(x => Metatag(x, (meta \ x).as[List[String]])

ここで、新しい Play 2.1-JSON-API (プロトタイプ) を使用したいと思います。

import play.api.libs.json._
import play.api.libs.functional.syntax._

object Metatags {  
  implicit val metatagsRead: Read[Metatags] = (
    (JsPath \ "description").read[String] and
    (JsPath \ "tags").read[List[Metatag]]
  )(Metatags.apply _, unlift(Metatags.unapply _))

  implicit val metatagRead: Read[Metatag] = (
    JsPath().key. ?? read[String] and              // ?!? read key
    JsPath().values. ?? read[List[String]]         // ?!? read value list
  )(Metatag.apply _, unlift(Metatag.unapply _))

}

case class Metatags(description: String, tags: List[Metatag])
case class Metatag(key: String, data: List[String])

JSON からキーを読み取るにはどうすればよいですか?

4

1 に答える 1

5

MetaTagこれは、クラスのカスタム リーダーを使用したソリューションです。JsValue読み取りは、をに変換するだけJsObjectで、便利なfieldSetメソッドがあります。

の場合MetaTags、マクロの開始は完全に機能します

object Application extends Controller {

  case class MetaTags(description: String, tags: List[MetaTag])
  case class MetaTag(key: String, data: List[String])

  implicit val readMetaTag = Reads(js => 
    JsSuccess(js.as[JsObject].fieldSet.map(tag => 
      MetaTag(tag._1, tag._2.as[List[String]])).toList))

  implicit val readMetaTags = Json.reads[MetaTags]

  def index = Action {
    val json = Json.obj(
      "description" -> "Hello world",
      "tags" -> Map(
        "key1" -> Seq("key1a", "key1b"),
        "key2" -> Seq("key2a"),
        "key3" -> Seq("Key3a", "key3b", "key3c")))

    val meta = json.as[MetaTags]
    Ok(meta.tags.map(_.data.mkString(",")).mkString("/"))
    // key1a,key1b/key2a/Key3a,key3b,key3c
  }

}
于 2013-01-14T19:48:40.097 に答える