2015-07-11 32 views
1

我是斯卡拉特拉的新手。我有一个带有JacksonJsonSupport的Servlet,它可以为REST端点提供对象列表。如何在Scalatra中将对象类型序列化为JSON?

class OperationsController extends MyappStack with JacksonJsonSupport { 

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

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

Operation由或AddingRemovingcase类实现。 如何将GET /响应中的特定类添加到值中?我想获得一个响应:

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

而不是

[ 
    { 
    "value": 100 
    } 
] 

哪里Adding是扩展Operation类。

+0

是否添加或删除有状态?你可以让它们成为案例对象吗? – ka4eli

+0

他们是操作的案例类。 'case class添加扩展操作'。他们没有额外的状态参数。 – dmydlarz

回答

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) 
    } 

    } 

} 
+0

的命题我会试试看,它看起来很有希望 – dmydlarz

+1

谢谢,这就是我一直在寻找:) – dmydlarz

1

我认为,最简单的办法是更新像

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

另一种方法是使用自定义序列化更新您的jsonFormats你的case类,我发现例如jsons的自定义序列here

+0

我对复制信息不感兴趣。此解决方案不满足我,但感谢 – dmydlarz

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 
    } 

} 
相关问题