使用Scalatra对Java和Scala对象进行序列化

时间:2016-06-06 16:34:14

标签: scala scalatra json4s

我继承了一个提供REST API的传统Scalatra应用程序。如果返回的对象是在其他case类上构建的case类,则返回对象的序列化将完美地工作。但是,如果返回从Java或Scala类创建的对象,则Scalatra不会对其进行序列化。我将只得到Object.toString()的结果。那么我还需要正确地序列化非案例类吗?

这是我的班级

stat

这是我的servlet:

lstat

1 个答案:

答案 0 :(得分:1)

json4s默认不支持非大小写类序列化。您需要为您的课程添加CustomSerializer

class IntervalSerializer extends CustomSerializer[Interval](format => (
  {
    // Deserialize
    case JObject(JField("start", JInt(s)) :: JField("end", JInt(e)) :: Nil) =>
      new Interval(s.longValue, e.longValue)
  },
  {
    // Serialize
    case x: Interval =>
      JObject(JField("start", JInt(BigInt(x.startTime))) ::
        JField("end",   JInt(BigInt(x.endTime))) :: Nil)
  }
  ))

您还需要将这些序列化程序添加到正在使用的jsonFormats中。

  protected implicit lazy val jsonFormats: Formats = DefaultFormats + FieldSerializer[Interval]()

这里是修改了json4s文档的示例,以显示正常类中返回序列化json的工作servlet。

import org.json4s._
import org.json4s.JsonAST.{JInt, JField, JObject}
import org.scalatra.json.JacksonJsonSupport

class Interval(start: Long, end: Long) {
  val startTime = start
  val endTime = end
}

class IntervalSerializer extends CustomSerializer[Interval](format => (
  {
    // Deserialize
    case JObject(JField("start", JInt(s)) :: JField("end", JInt(e)) :: Nil) =>
      new Interval(s.longValue, e.longValue)
  },
  {
    // Serialize
    case x: Interval =>
      JObject(JField("start", JInt(BigInt(x.startTime))) ::
        JField("end",   JInt(BigInt(x.endTime))) :: Nil)
  }
  ))

class IntervalServlet extends ScalatraServlet with ScalateSupport with JacksonJsonSupport {

  get("/intervalsample") {
    contentType = "application/json"

    val interval = new Interval(1, 2)

    Extraction.decompose(interval)
  }

  protected implicit lazy val jsonFormats: Formats = DefaultFormats + FieldSerializer[Interval]()

}