Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Add JSONP support to the JsonSupport trait.

  • Loading branch information...
commit 4489f04b0fd8ba7cf95b6aec43e51d329c32d53e 1 parent 6297163
Phil Wills authored February 07, 2012
18  lift-json/src/main/scala/org/scalatra/liftjson/JsonSupport.scala
@@ -9,6 +9,15 @@ import net.liftweb.json.JsonAST.JValue
9 9
  */
10 10
 trait JsonSupport extends ScalatraKernel {
11 11
 
  12
+  /**
  13
+   * If a request is made with a parameter in jsonpCallbackParameterNames it will
  14
+   * be assumed that it is a JSONP request and the json will be returned as the
  15
+   * argument to a function with the name specified in the corresponding parameter.
  16
+   *
  17
+   * By default no parameterNames will be checked
  18
+   */
  19
+  def jsonpCallbackParameterNames:  Iterable[String] = None
  20
+
12 21
   override protected def contentTypeInferrer = ({
13 22
     case _ : JValue => "application/json; charset=utf-8"
14 23
   }: ContentTypeInferrer) orElse super.contentTypeInferrer
@@ -16,8 +25,13 @@ trait JsonSupport extends ScalatraKernel {
16 25
   override protected def renderPipeline = ({
17 26
     case jv : JValue =>
18 27
       import net.liftweb._
19  
-      json.compact(json.render(jv)).getBytes("UTF-8")
20  
-  }: RenderPipeline) orElse super.renderPipeline
  28
+      val jsonString = json.compact(json.render(jv))
21 29
 
  30
+      val jsonWithCallback = for {
  31
+        paramName <- jsonpCallbackParameterNames
  32
+        callback <- params.get(paramName)
  33
+      } yield "%s(%s);" format (callback, jsonString)
22 34
 
  35
+      (jsonWithCallback.headOption.getOrElse(jsonString)).getBytes("UTF-8")
  36
+  }: RenderPipeline) orElse super.renderPipeline
23 37
 }
28  lift-json/src/test/scala/org/scalatra/liftjson/JsonSupportTest.scala
@@ -4,8 +4,8 @@ import org.scalatra.test.scalatest.ScalatraFunSuite
4 4
 import org.scalatra.ScalatraServlet
5 5
 
6 6
 class JsonSupportTest extends ScalatraFunSuite {
7  
-  val servletHolder = addServlet(classOf[JsonSupportTestServlet], "/*")
8  
-  servletHolder.setInitOrder(1) // force load on startup
  7
+  addServlet(classOf[JsonSupportTestServlet], "/*")
  8
+  addServlet(classOf[JsonPTestServlet], "/p/*")
9 9
 
10 10
   test("JSON support test") {
11 11
     get("/json") {
@@ -13,6 +13,20 @@ class JsonSupportTest extends ScalatraFunSuite {
13 13
       response.body should equal ("""{"k1":"v1","k2":"v2"}""")
14 14
     }
15 15
   }
  16
+
  17
+  test("JSONP callback test with no callback name specified") {
  18
+    get("/json", "callback" -> "function") {
  19
+      response.mediaType should equal (Some("application/json"))
  20
+      response.body should equal ("""{"k1":"v1","k2":"v2"}""")
  21
+    }
  22
+  }
  23
+
  24
+  test("JSONP callback test with callback name specified") {
  25
+    get("/p/jsonp", "callback" -> "function") {
  26
+      response.mediaType should equal (Some("application/json"))
  27
+      response.body should equal ("""function({"k1":"v1","k2":"v2"});""")
  28
+    }
  29
+  }
16 30
 }
17 31
 
18 32
 
@@ -23,3 +37,13 @@ class JsonSupportTestServlet extends ScalatraServlet with JsonSupport {
23 37
       ("k2" -> "v2")
24 38
   }
25 39
 }
  40
+
  41
+class JsonPTestServlet extends ScalatraServlet with JsonSupport {
  42
+  override def jsonpCallbackParameterNames = Some("callback")
  43
+
  44
+  get("/jsonp") {
  45
+    import net.liftweb.json.JsonDSL._
  46
+    ("k1" -> "v1") ~
  47
+    ("k2" -> "v2")
  48
+  }
  49
+}

0 notes on commit 4489f04

Please sign in to comment.
Something went wrong with that request. Please try again.