如何在Scalatra中将对象类型序列化为JSON?

时间:2015-07-11 20:57:01

标签: json scala scalatra json4s

我是Scalatra的新手。我有一个带有JacksonJsonSupport的servlet,它为REST端点提供了对象列表。

class OperationsController extends MyappStack with JacksonJsonSupport {

  before() {
    contentType = formats("json")
  }

  get("/") {
    Data.operations
  }
}

OperationAddingRemoving 案例类实施。 如何将特定类添加到GET /响应值?我想作为回应:

[
  {
     "operation": "Adding",
     "value": 100
  }
]

而不是

[
  {
     "value": 100
  }
]

Adding是一个扩展Operation的类。

3 个答案:

答案 0 :(得分:1)

我认为,最简单的方法是更新您的案例类,如

case class Adding(value: Int, operation: String = "Adding") 
case class Removing (value: Int, operation: String = "Removing") 

另一种方法是使用自定义序列化程序更新jsonFormats,我找到了jsons自定义序列化的示例here

答案 1 :(得分:1)

对于多态值,json4s可以将具体类型添加为附加字段。这称为“类型提示”:

[{
    "jsonClass": "Adding",
    "value": 10
}, {
    "jsonClass": "Adding",
    "value": 20
}, {
    "jsonClass": "Removing",
    "value": 20
}]

例如,使用ShortTypeHints

import org.json4s.{ShortTypeHints, DefaultFormats}
import org.scalatra.ScalatraServlet
import org.scalatra.json.JacksonJsonSupport
import org.scalatra.test.specs2.MutableScalatraSpec

sealed trait Operation
case class Adding(value: Int) extends Operation
case class Removing(value: Int) extends Operation

class json1 extends MutableScalatraSpec {

  mount(new ScalatraServlet with JacksonJsonSupport {

    def typeHints = new ShortTypeHints(List(
      classOf[Adding], classOf[Removing]
    ))

    implicit lazy val jsonFormats = DefaultFormats + typeHints

    before() {
      contentType = formats("json")
    }

    get("/") {
      List(
        Adding(10),
        Adding(20),
        Removing(20)
      )
    }

  }, "/*")

  "Should return a list of operations" in {

    get("/", headers = Seq("Content-type" -> "application/json")) {
      println(body)
      status should beEqualTo(200)
    }

  }

}

答案 2 :(得分:0)

json_conversion.scala文件我们创建了特征SimpleMongoDbJsonConversion,我们在MyScalatraServlet.scala文件中使用它,参见下面的例子。

<强> json_conversion.scala

package com.example.app

import org.scalatra._
import com.mongodb.casbah.Imports._

trait SimpleMongoDbJsonConversion extends ScalatraBase with ApiFormats {

  def renderMongo = {
    case dbo: DBObject =>
      contentType = formats("json")
      dbo.toString

    case xs: TraversableOnce[_] =>
      contentType = formats("json")
      val l = xs map (x => x.toString) mkString(",")
      "[" + l + "]"

  }: RenderPipeline

  override protected def renderPipeline = renderMongo orElse super.renderPipeline

}

<强> MyScalatraServlet.scala

package com.example.app

import org.scalatra._
import com.mongodb.casbah.Imports._

class MyScalatraMongoServlet(mongoColl: MongoCollection) extends MyScalatraWebAppStack with SimpleMongoDbJsonConversion {

  get("/") {
    <html>
      <body>
        <h1>Hello, world!</h1>
        Say <a href="hello-scalate">hello to Scalate</a>.
      </body>
    </html>
  }

  post("/insert") {
    val key = params("key")
    val value = params("value")
    val newObj = MongoDBObject(key->value)
    mongoColl += newObj
  }

  get("/users") {
    mongoColl.find()
    for { x <- mongoColl } yield x
  }

}