Documentation

You are viewing the documentation for the 2.3.x release series. The latest stable release series is 2.4.x.

§JSON temelleri

Modern web uygulamaları sıklıkla JSON (JavaScript Object Notation) formatı içinde veriyi ayrıştırmaya ve oluşturmaya ihtiyaç duyar. Play JSON JSON kütüphanesi ile bunu destekler.

JSON hafif bir veri takas formatıdır ve aşağıdaki gibi görünür:

{
  "name" : "Watership Down",
  "location" : {
    "lat" : 51.235685,
    "long" : -1.309197
  },
  "residents" : [ {
    "name" : "Fiver",
    "age" : 4,
    "role" : null
  }, {
    "name" : "Bigwig",
    "age" : 6,
    "role" : "Owsla"
  } ]
}

JSON hakkında daha fazla bilgi almak json.org adresine bakabilirsiniz.

§Play JSON Kütüphanesi

play.api.libs.json JSON verisi sunmak için gereken veri yapılarını ve bu veri yapıları ile
diğer veri sunuş biçimleri arasında çevrim yapmak için gerekli olaran araçları içerir. İlgili tipler:

§JsValue

Herhangi bir JSON değerini sunmak için var olan bir trait’dir. JSON kütüphanesi geçerli JSON tiplerini gösterebilmek için JsValue’den türetilmiş bir case class’a sahiptir:

gibi çeşitli JsValue tipleri kullanılır, sizde herhangi bir JSON yapısı oluşturabilirsiniz.

§Json

Json objesi gerekli yardımcı bileşenleri sağlar, öncelikli olarak JsValue yapıları arasındaki çevirme işlemleri içindir.

§JsPath

JsValue yapısın içine bir yol sunar, XML için olan XPath’e benzerdir. JsValue yapıları içersinde gezinmek için ve örtük dönüştürücüler için desenler içinde kullanılır.

§Bir JsValue’ye çevirmek

§String ayrıştırma kullanarak

import play.api.libs.json._

val json: JsValue = Json.parse("""
{
  "name" : "Watership Down",
  "location" : {
    "lat" : 51.235685,
    "long" : -1.309197
  },
  "residents" : [ {
    "name" : "Fiver",
    "age" : 4,
    "role" : null
  }, {
    "name" : "Bigwig",
    "age" : 6,
    "role" : "Owsla"
  } ]
}
""")

§Sınıf yapısı kullanarak

import play.api.libs.json._

val json: JsValue = JsObject(Seq(
  "name" -> JsString("Watership Down"),
  "location" -> JsObject(Seq("lat" -> JsNumber(51.235685), "long" -> JsNumber(-1.309197))),
  "residents" -> JsArray(Seq(
    JsObject(Seq(
      "name" -> JsString("Fiver"),
      "age" -> JsNumber(4),
      "role" -> JsNull
    )),
    JsObject(Seq(
      "name" -> JsString("Bigwig"),
      "age" -> JsNumber(6),
      "role" -> JsString("Owsla")
    ))
  ))
))      

Json.obj and Json.arr yapıyı bir parça basitleştirebilir. Şunu unutmayın ki çoğu değer JsValue sınıf ile belirtik olarak sarmalanmaya ihtiyacı yoktur, fabrika metodları örtük dönüşüm kullanır (daha fazlası aşağıda).

import play.api.libs.json.{JsNull,Json,JsString,JsValue}

val json: JsValue = Json.obj(
  "name" -> "Watership Down",
  "location" -> Json.obj("lat" -> 51.235685, "long" -> -1.309197),
  "residents" -> Json.arr(
    Json.obj(
      "name" -> "Fiver",
      "age" -> 4,
      "role" -> JsNull
    ),
    Json.obj(
      "name" -> "Bigwig",
      "age" -> 6,
      "role" -> "Owsla"
    )
  )
)

§Writes çeviricilerini kullanmak

Scala’dan JsValue’ye çevirme işlemi Json.toJson[T](T)(implicit writes: Writes[T]) yardımcı metodu ile gerçekleşir. Bu fonksiyonel bağlılık Writes[T] tipi üzerindedir, T değeri bir JsValue değerine dönüştürülür.

Play JSON API temel tipler için örtülü olarak Writes sağlar. Int, Double, String ve Boolean bunların içindedir. Aynı zamanda Writes, Writes[T] herhangi bir T tipi ile var olan herhangi bir tip kolleksiyonunuda destekler.

import play.api.libs.json._

// basic types
val jsonString = Json.toJson("Fiver")
val jsonNumber = Json.toJson(4)
val jsonBoolean = Json.toJson(false)

// collections of basic types
val jsonArrayOfInts = Json.toJson(Seq(1, 2, 3, 4))
val jsonArrayOfStrings = Json.toJson(List("Fiver", "Bigwig"))

Kendi modellerinizi JsValues’e dönüştürebilirisiniz, örtülü olarak Writes çeviricileri tanımlamalı ve kapsamın içinde olmasını sağlamalısınız.

case class Location(lat: Double, long: Double)
case class Resident(name: String, age: Int, role: Option[String])
case class Place(name: String, location: Location, residents: Seq[Resident])
import play.api.libs.json._

implicit val locationWrites = new Writes[Location] {
  def writes(location: Location) = Json.obj(
    "lat" -> location.lat,
    "long" -> location.long
  )
}

implicit val residentWrites = new Writes[Resident] {
  def writes(resident: Resident) = Json.obj(
    "name" -> resident.name,
    "age" -> resident.age,
    "role" -> resident.role
  )
}

implicit val placeWrites = new Writes[Place] {
  def writes(place: Place) = Json.obj(
    "name" -> place.name,
    "location" -> place.location,
    "residents" -> place.residents)
}

val place = Place(
  "Watership Down",
  Location(51.235685, -1.309197),
  Seq(
    Resident("Fiver", 4, None),
    Resident("Bigwig", 6, Some("Owsla"))
  )
)

val json = Json.toJson(place)

Alternatif olarak birleştiren desenle kendiniz Writes tanımlayabilirsiniz.

Not: Birleştiren desen konusu JSON Reads/Writes/Formats Combinators detaylı bir şekilde anlatılmıştır.

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

implicit val locationWrites: Writes[Location] = (
  (JsPath \ "lat").write[Double] and
  (JsPath \ "long").write[Double]
)(unlift(Location.unapply))

implicit val residentWrites: Writes[Resident] = (
  (JsPath \ "name").write[String] and
  (JsPath \ "age").write[Int] and
  (JsPath \ "role").writeNullable[String]
)(unlift(Resident.unapply))

implicit val placeWrites: Writes[Place] = (
  (JsPath \ "name").write[String] and
  (JsPath \ "location").write[Location] and
  (JsPath \ "residents").write[Seq[Resident]]
)(unlift(Place.unapply))

§Bir JsValue yapısında gezinme

Bir JsValue yapısında gezinebilir ve belirli değerleri alabilirsiniz. Sözdizim ve fonksiyonellik olarak Scala XML işlemeye benzerdir.

Not: Aşağıdaki örnekler bir önceki örnekte oluşturulan JsValue yapısına uygulanmıştır.

§Basit yol \

Bir JsValue’ye \ operatörünü uygulamak bunun bir JsObject olduğunu farz edersek alan argümanına eş olan özelliği döndürecektir.

val lat = json \ "location" \ "lat"
// returns JsNumber(51.235685)

§Rekürsif yol \\

\\ operatörünü uygulamak mevcut objede ve aynı soydan olanlarda alan için bir arama yapacaktır.

val names = json \\ "name" 
// returns Seq(JsString("Watership Down"), JsString("Fiver"), JsString("Bigwig"))

§İndeks bakınma (JsArray’lar için)

apply operatörü ile indeks numarası kullanarak Bir JsArray içindeki değere ulaşabilirisiniz.

val bigwig = (json \ "residents")(1)
// returns {"name":"Bigwig","age":6,"role":"Owsla"}

§Bir JsValue’den çevirmek

§String yardımcıları kullanarak

Küçültülmüş:

val minifiedString: String = Json.stringify(json)
{"name":"Watership Down","location":{"lat":51.235685,"long":-1.309197},"residents":[{"name":"Fiver","age":4,"role":null},{"name":"Bigwig","age":6,"role":"Owsla"}]}

Okunabilir:

val readableString: String = Json.prettyPrint(json)
{
  "name" : "Watership Down",
  "location" : {
    "lat" : 51.235685,
    "long" : -1.309197
  },
  "residents" : [ {
    "name" : "Fiver",
    "age" : 4,
    "role" : null
  }, {
    "name" : "Bigwig",
    "age" : 6,
    "role" : "Owsla"
  } ]
}

§JsValue.as/asOpt kullanmak

Bir JsValue’yi başka tipe çevirmenin en kolay yolu JsValue.as[T](implicit fjs: Reads[T]): T kullanmaktır. Bir JsValue’yi T tipine çevirmek için (Writes[T]’nin tersi) Reads[T] tipinde bir örtülü çevirici olması zorunludur. Writes ile JSON API temel tipler için Reads sağlar.

val name = (json \ "name").as[String]
// "Watership Down"

val names = (json \\ "name").map(_.as[String])
// Seq("Watership Down", "Fiver", "Bigwig")

Eğer yol bulunamazsa yada çevirme imkansızsa, as metodu bir JsResultException fırlatacaktır. JsValue.asOpt[T](implicit fjs: Reads[T]): Option[T] güvenli bir metoddur.

val nameOption = (json \ "name").asOpt[String]
// Some("Watership Down")

val bogusOption = (json \ "bogus").asOpt[String]
// None

Buna rağman asOpt metodu daha güvenlidir, herhangi bir hata bilgisi kaybolmaz.

§Doğrulama Kullanmak

Bir JsValue’den başka bir tipe dönüştürmek için tercih edilen yol validate metodunun kullanılmasıdır (Reads tipinde bir argüman alır). Bu hem doğrulama hem de çevirme işlemini sağlar, JsResult tipinde bir sonuç döndürür. JsResult iki sınıf tarafından uygulanmıştır:

Doğrulama sonucunu işlemek için çeşitli desenler uygulayabilirsiniz:

val json = { ... }

val nameResult: JsResult[String] = (json \ "name").validate[String]

// Pattern matching
nameResult match {
  case s: JsSuccess[String] => println("Name: " + s.get)
  case e: JsError => println("Errors: " + JsError.toFlatJson(e).toString()) 
}

// Fallback value
val nameOrFallback = nameResult.getOrElse("Undefined")

// map
val nameUpperResult: JsResult[String] = nameResult.map(_.toUpperCase())

// fold
val nameOption: Option[String] = nameResult.fold(
  invalid = {
    fieldErrors => fieldErrors.foreach(x => {
      println("field: " + x._1 + ", errors: " + x._2)
    })
    None
  },
  valid = { 
    name => Some(name)
  }
)

§JsValue’den bir modele

JsValue’den bir modele çevirmek için, örtülü bir Reads[T] tanımlamalısınız. T sizin modelinizin tipini gösterir.

Not: Desen Reads’i uygulaman için kullanılır, özelliştirilmiş doğrulama JSON Reads/Writes/Formats Combinators konusunda anlatılmıştır.

case class Location(lat: Double, long: Double)
case class Resident(name: String, age: Int, role: Option[String])
case class Place(name: String, location: Location, residents: Seq[Resident])
import play.api.libs.json._
import play.api.libs.functional.syntax._

implicit val locationReads: Reads[Location] = (
  (JsPath \ "lat").read[Double] and
  (JsPath \ "long").read[Double]
)(Location.apply _)

implicit val residentReads: Reads[Resident] = (
  (JsPath \ "name").read[String] and
  (JsPath \ "age").read[Int] and
  (JsPath \ "role").readNullable[String]
)(Resident.apply _)

implicit val placeReads: Reads[Place] = (
  (JsPath \ "name").read[String] and
  (JsPath \ "location").read[Location] and
  (JsPath \ "residents").read[Seq[Resident]]
)(Place.apply _)


val json = { ... }

val placeResult: JsResult[Place] = json.validate[Place]
// JsSuccess(Place(...),)

val residentResult: JsResult[Resident] = (json \ "residents")(1).validate[Resident]
// JsSuccess(Resident(Bigwig,6,Some(Owsla)),)

Sonraki: HTTP ile JSON


Dokümantasyonun bu çevirisi Play ekibi tarafından yapılmamaktadır. Eğer bir hata bulduysanız, bu sayfanın kaynak kodu burada bulunmaktadır. Dokümantasyon yönergelerini okuduktan sonra lütfen katkı yapmaktan çekinmeyin.