5

Scalaケースクラスがあります

case class Example(name: String, number: Int)

およびコンパニオンオブジェクト

object Example {
  implicit object ExampleFormat extends Format[Example] {
    def reads(json: JsValue) = {
      JsSuccess(Example(
       (json \ "name").as[String],
       (json \ "number").as[Int]))
     }

     def writes(...){}
   }
}

JSONをScalaオブジェクトに変換します。

JSONが有効な場合(つまり{"name":"name","number": 0}、正常に機能します。ただし、numberが引用符で囲まれている場合{"name":"name","number":"0"}、エラーが発生します:validate.error.expected.jsnumber

そのような場合に暗黙的に変換する方法はありStringますIntか(番号が有効であると仮定して)?

4

1 に答える 1

8

ヘルパーのおかげで、Json コンビネーターを使用してこのケースを簡単に処理できますorElse。Play2.1 で導入された新しい構文で json フォーマッタを書き直しました

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

object Example {
  // Custom reader to handle the "String number" usecase
  implicit val reader = (
    (__ \ 'name).read[String] and
    ((__ \ 'number).read[Int] orElse (__ \ 'number).read[String].map(_.toInt))
  )(Example.apply _)

  // write has no specificity, so you can use Json Macro
  implicit val writer = Json.writes[Example] 
}

object Test extends Controller {
  def index = Action {
    val json1 = Json.obj("name" -> "Julien", "number" -> 1000).as[Example]
    val json2 = Json.obj("name" -> "Julien", "number" -> "1000").as[Example]
    Ok(json1.number + " = " + json2.number) // 1000 = 1000
  }
}
于 2013-01-27T20:43:47.340 に答える