Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to render JSON response in Play framework v2.0 (latest build from GIT)

I'm trying to render some response like this

def doAjax = Action { request =>
    object MyResult {
        val resultCode = 0
        val resultTextMessage = "sss" 
    }
    Ok(Json(MyResult)) // It's not working anymore - not compiling in v2.0!
}   

but how to map my object (MyResult) to JSON with Play 2.0? In Play 1.0 with scala module I did successfully the following:

def dosomeaj = {
    object MyResult{
        val resultCode = 0
        val resultTextMessage = "sss" 
    }
    Json(MyResult) // It's working in 1.0
}    
like image 699
abdolence Avatar asked Jan 01 '12 20:01

abdolence


3 Answers

EDIT2

New Wiki link for v2.1. The old link below is not working anymore.

EDIT

We'll all be happy to read the new Wiki entry for this point. Check this out


PREVIOUS

Here is the comment from the community about the state of Json support in play 2.0. link to Post

They are moving from Jackson to a philosophy inspired by SJSON that offers more control on the un/marshalling, that brings facilities to manage them, w/o the overhead of Reflection (which I agree with them is a pain for performance and is fragile against Class changes...)

So here is what you can read on the post:

case class Blah(blah: String)

// if you want to directly serialize/deserialize, you need to write yourself a formatter right now
implicit object BlahFormat extends Format[Blah] {
    def reads(json: JsValue): Blah = Blah((json \ "blah").as[String])
    def writes(p: Blah): JsValue = JsObject(List("blah" -> JsString(p.blah)))

}

def act = Action { implicit request =>
   // to get a Blah object from request content
   val blah = Json.parse(request.body.asText.get).as[Blah]

   // to return Blah as application/json, you just have to convert your Blah to a JsValue and give it to Ok()
   Ok(toJson(blah))
}

In the second link (SJSON), I propose you to pay special attention to the generic formatting possible by using case class and their deconstruction method (unapply).

like image 183
9 revs, 2 users 93% Avatar answered Oct 21 '22 07:10

9 revs, 2 users 93%


Play 2 comes with Jerkson

case class Blah(blah: String)
import com.codahale.jerksHon.Json._
def act = Action { implicit request =>
    Ok(generate(parse[Blah](request.body.asText.get))).as("application/json")
}

This code will deserialize and reserialize the json.

For more information https://github.com/codahale/jerkson

like image 37
Ivan Meredith Avatar answered Oct 21 '22 07:10

Ivan Meredith


I've found this solution in Play integration tests right now.

It's require to define in app/models/MyResult2.scala with this content:

case class MyResult2(resultCode: Int, resultTextMessage: String)

object Protocol {
    implicit object MyResult2Format extends Format[MyResult2] {
        def writes(o: MyResult2): JsValue = JsObject(
            List("resultCode" -> JsNumber(o.resultCode),
                "resultTextMessage" -> JsString(o.resultTextMessage)
            )
        )

        def reads(json: JsValue): MyResult2 = MyResult2(
            (json \ "resultCode").as[Int],
            (json \ "resultTextMessage").as[String]
        )
    }
}

And after this you can use it in your controller class like this:

import play.api._
import play.api.mvc._
import play.api.libs.json._
import models._
import models.Protocol._

object Application extends Controller {    
    def doAjax = Action { request =>
        Ok(toJson(MyResult2(0, "Ney")))
    }
}

It's now required some manual static marshalling code.

like image 32
abdolence Avatar answered Oct 21 '22 08:10

abdolence