如何在 Scalatra 中将对象类型序列化为 JSON?
How to serialize object type to JSON in Scalatra?
我是 Scalatra 的新手。我有一个带有 JacksonJsonSupport 的 servlet,它为带有对象列表的 REST 端点提供服务。
class OperationsController extends MyappStack with JacksonJsonSupport {
before() {
contentType = formats("json")
}
get("/") {
Data.operations
}
}
Operation
由 Adding
或 Removing
case classes 实现。
如何将特定的 class 添加到 GET /
响应中?我想得到回应:
[
{
"operation": "Adding",
"value": 100
}
]
而不是
[
{
"value": 100
}
]
其中 Adding
是扩展 Operation
.
的 class
我认为,最简单的方法是像
一样更新您的案例 类
case class Adding(value: Int, operation: String = "Adding")
case class Removing (value: Int, operation: String = "Removing")
另一种方法是使用自定义序列化程序更新您的 jsonFormats,我找到了 jsons 自定义序列化的示例 here
对于多态值,json4s 可以将具体类型添加为附加字段。这称为 "type hint":
[{
"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)
}
}
}
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
}
}
我是 Scalatra 的新手。我有一个带有 JacksonJsonSupport 的 servlet,它为带有对象列表的 REST 端点提供服务。
class OperationsController extends MyappStack with JacksonJsonSupport {
before() {
contentType = formats("json")
}
get("/") {
Data.operations
}
}
Operation
由 Adding
或 Removing
case classes 实现。
如何将特定的 class 添加到 GET /
响应中?我想得到回应:
[
{
"operation": "Adding",
"value": 100
}
]
而不是
[
{
"value": 100
}
]
其中 Adding
是扩展 Operation
.
我认为,最简单的方法是像
一样更新您的案例 类case class Adding(value: Int, operation: String = "Adding")
case class Removing (value: Int, operation: String = "Removing")
另一种方法是使用自定义序列化程序更新您的 jsonFormats,我找到了 jsons 自定义序列化的示例 here
对于多态值,json4s 可以将具体类型添加为附加字段。这称为 "type hint":
[{
"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)
}
}
}
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
}
}