我正在编写一个RESTful接口,我想为Jmber Data准备好JSON,并为其做好准备。 皱纹是Ember Data想要的实体名称和我尝试的两个库,sp1-json和json4s,似乎不容易这样做。
所需的Ember Data格式
{
"coursePhoto": {
"photoId": 1
}
}
当前默认格式:
{"photoId":15}
这应该来自一个案例类:
case class CoursePhoto(photoId: Long)
我确实使用以下自定义代码运行它:
object PtolemyJsonProtocol extends DefaultJsonProtocol {
implicit object CoursePhotoFormat extends RootJsonFormat[CoursePhoto] {
def write(cp: CoursePhoto) =
JsObject("CoursePhoto" -> JsObject("photoId" -> JsNumber(cp.photoId)))
def read(value: JsValue) = value match {
case coursePhotoJsObject: JsObject => {
CoursePhoto(coursePhotoJsObject.getFields("CoursePhoto")(0).asJsObject
.getFields("photos")(0).asInstanceOf[JsArray].elements(0)
.asInstanceOf[JsNumber].value.toLong)
}
case _ => deserializationError("CoursePhoto expected")
}
}
对于所有asInstanceOf
和(0)
,该代码似乎非常脆弱和丑陋。
鉴于我在Spray中使用Scala编写什么是获得命名根JSON输出的好方法?我很高兴能与任何与Spray很好地集成的JSON库做到这一点,而且性能相当高。
答案 0 :(得分:0)
以下是否解决了您的问题?
scala> import spray.json._
import spray.json._
scala> import DefaultJsonProtocol._
import DefaultJsonProtocol._
scala> case class CoursePhoto(photoId: Long)
defined class CoursePhoto
scala> case class CoursePhotoEmber(coursePhoto: CoursePhoto)
defined class CoursePhotoEmber
scala> implicit val jsonFormatCoursePhoto = jsonFormat1(CoursePhoto)
jsonFormatCoursePhoto: spray.json.RootJsonFormat[CoursePhoto] = spray.json.ProductFormatsInstances$$anon$1@6f5d66b6
scala> implicit val jsonFormatCoursePhotoEmber = jsonFormat1(CoursePhotoEmber)
jsonFormatCoursePhotoEmber: spray.json.RootJsonFormat[CoursePhotoEmber] = spray.json.ProductFormatsInstances$$anon$1@401a0d22
scala> """{ "coursePhoto": { "photoId": 1 } }""".parseJson.convertTo[CoursePhotoEmber]
res0: CoursePhotoEmber = CoursePhotoEmber(CoursePhoto(1))
scala> res0.toJson
res1: spray.json.JsValue = {"coursePhoto":{"photoId":1}}
答案 1 :(得分:0)
这个问题让我想知道是否有可能以可重复使用的方式进行。我相信我已经找到了一种合理的方法来为多种类型做到这一点。
object PtolemyJsonProtocol extends DefaultJsonProtocol {
implicit val CoursePhotoFormat = new NamedRootFormat("CoursePhoto", jsonFormat1(CoursePhoto))
}
import PtolemyJsonProtocol._
class NamedRootFormat[T](rootName: String, delegate: RootJsonFormat[T]) extends RootJsonFormat[T] {
def write(obj: T): JsValue = {
JsObject((rootName, delegate.write(obj)))
}
def read(json: JsValue): T = json match {
case parentObject: JsObject => {
delegate.read(parentObject.getFields(rootName).head)
}
case _ => deserializationError("CoursePhoto expected")
}
}