Play 2.1 JSON in Scala object

I have a Scala class class

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

and companion object

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

     def writes(...){}
   }
}

which converts JSON to a Scala object.

When JSON is valid (ie {"name":"name","number": 0}, it works fine, however when. numberIs in quotes {"name":"name","number":"0"}, I get an error message: validate.error.expected.jsnumber.

Is there a way to implicitly convert Stringto Intin that case (assuming the number is valid)?

+5
source share
1 answer

You can easily handle this case with Json combinators, thanks to a helper orElse. I rewrote your json formater with the new syntax introduced in Play2.1

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
  }
}
+8
source

All Articles