I run through the JSON documentation at http://www.playframework.com/documentation/2.2.x/ScalaJsonRequests but didn't find what I needed. What I need is make my class being able to be converted to JSON like this:
# model
case class MyClass(a: Int, b: String ....)
# controller
def myAction = Action {
val myClass = getMyClass()
Ok(toJson(myClass))
}
So wherever I call Ok(toJson(myClass))
, it converts to JSON by itself. How can I do this?
P.S. Sorry, I forgot to mention MyClass has java.util.UUID
as an Id
and some other class as a field:
case class MyClass(id: UUID, a: Int, b: String, c: MyClass2 ....)
So Json.writes[MyClass]
doesn't work at least because of UUID
.
You could add a macro-generated Writes[MyClass]
to companion object of MyClass
like this:
object MyClass {
implicit val myClassWrites = Json.writes[MyClass]
}
Method toJson
implicitly accepts parameter of type Writes[T]
. Compiler tries to find such implicit value and companion object of MyClass
is always in scope when type parameter T
is MyClass
, so you don't have to import myClassWrites
manually.
See also Where does Scala look for implicits?.
Json.writes
requires implicit Writes
for all constructor parameters.
case class MyClass(id: UUID, a: Int, b: String, c: MyClass2)
If MyClass2
is a case class you should create Writes[MyClass2]
using Json.writes
in its companion object.
For java.util.UUID
you should create Writes
manually, for instance:
implicit val uuidWrites: Writes[UUID] = Writes{ uuid => JsString(uuid.toString) }
You could create uuidWrites
in some helper object and than import when you need it like this:
object MyClass {
import UuidHelper.uuidWrites
// note that you don't have to import MyClass2.myClass2Writes here
implicit val myClassWrites = Json.writes[MyClass]
}