Skip to content

Instantly share code, notes, and snippets.

@tototoshi
Created May 25, 2012 12:45
Show Gist options
  • Save tototoshi/2787860 to your computer and use it in GitHub Desktop.
Save tototoshi/2787860 to your computer and use it in GitHub Desktop.
play + lift-json
package controllers
import play.api._
import play.api.mvc._
import play.api.http._
import play.api.libs.iteratee._
import play.api.libs.iteratee.Input._
import net.liftweb.json.{ JValue => LiftJValue, _ }
import net.liftweb.json.Extraction._
object LiftJsonParser {
def tolerantJson(maxLength: Int): BodyParser[LiftJValue] = BodyParser("json, maxLength=" + maxLength) { request =>
play.api.libs.iteratee.Traversable.takeUpTo[Array[Byte]](maxLength).apply(Iteratee.consume[Array[Byte]]().map { bytes =>
scala.util.control.Exception.allCatch[LiftJValue].either {
JsonParser.parse(new String(bytes, request.charset.getOrElse("utf-8")))
}.left.map { e =>
(Play.maybeApplication.map(_.global.onBadRequest(request, "Invalid Json")).getOrElse(Results.BadRequest), bytes)
}
}).flatMap(Iteratee.eofOrElse(Results.EntityTooLarge))
.flatMap {
case Left(b) => Done(Left(b), Empty)
case Right(it) => it.flatMap {
case Left((r, in)) => Done(Left(r), El(in))
case Right(json) => Done(Right(json), Empty)
}
}
}
def tolerantJson: BodyParser[LiftJValue] = tolerantJson(BodyParsers.parse.DEFAULT_MAX_TEXT_LENGTH)
def json(maxLength: Int): BodyParser[LiftJValue] = BodyParsers.parse.when(
_.contentType.exists(m => m == "text/json" || m == "application/json"),
tolerantJson(maxLength),
request => Play.maybeApplication.map(_.global.onBadRequest(request, "Expecting text/json or application/json body")).getOrElse(Results.BadRequest)
)
def json: BodyParser[LiftJValue] = json(BodyParsers.parse.DEFAULT_MAX_TEXT_LENGTH)
}
object Application extends Controller {
def index = Action(LiftJsonParser.json) { request =>
println(request.body)
Ok
}
}
//curl --header "Content-type: application/json" --request POST --data '{"name": "Guillaume"}' http://localhost:9000/
/*
[info] play - Application started (Dev)
JObject(List(JField(name,JString(Guillaume))))
*/
package controllers
import play.api._
import play.api.mvc._
import play.api.http._
import net.liftweb.json.{ JValue => LiftJValue, _ }
import net.liftweb.json.Extraction._
object Application extends Controller {
case class User(id: Long, name: String, friends: List[User])
def index = Action {
val peter = User(1, "peter", Nil)
implicit val format = DefaultFormats
implicit def writeableOf_LiftJValue(implicit codec: Codec): Writeable[LiftJValue] = {
Writeable[LiftJValue](jval => codec.encode((pretty(render(jval)))))
}
implicit def contentTypeOf_JsValue(implicit codec: Codec): ContentTypeOf[LiftJValue] = {
ContentTypeOf[LiftJValue](Some(ContentTypes.JSON))
}
Ok(decompose(peter))
}
}
/*
$ curl -v localhost:9000
* About to connect() to localhost port 9000 (#0)
* Trying 127.0.0.1... connected
> GET / HTTP/1.1
> User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
> Host: localhost:9000
> Accept:
>
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< Content-Length: 46
<
{
"id":1,
"name":"peter",
"friends":[]
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment