Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
(Un)在Spray上使用Scala case类为余烬数据命名根的marshall JSON_Scala_Ember Data_Spray_Spray Json_Json4s - Fatal编程技术网

(Un)在Spray上使用Scala case类为余烬数据命名根的marshall JSON

(Un)在Spray上使用Scala case类为余烬数据命名根的marshall JSON,scala,ember-data,spray,spray-json,json4s,Scala,Ember Data,Spray,Spray Json,Json4s,我正在编写一个RESTful接口,我希望为Ember数据整理和解压JSON。 问题在于,Ember Data需要实体名称,而我尝试过的两个库spray json和json4s似乎并不容易做到这一点 所需格式 当前默认格式: {"photoId":15} 这应该来自一个案例类: case class CoursePhoto(photoId: Long) 我确实使用以下自定义代码运行了它: object PtolemyJsonProtocol extends DefaultJsonProtoco

我正在编写一个RESTful接口,我希望为Ember数据整理和解压JSON。 问题在于,Ember Data需要实体名称,而我尝试过的两个库spray json和json4s似乎并不容易做到这一点

所需格式

当前默认格式:

{"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")
  }
}
这段代码看起来非常脆弱和丑陋,所有的
都是
(0)


考虑到我正在使用Scala编写Spray,获得命名根JSON输出的好方法是什么?我很乐意使用任何与Spray很好地集成并且性能合理的JSON库来实现这一点。

以下内容是否解决了您的问题

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

这个问题让我怀疑是否有可能以一种可重用的方式来实现它。我相信我已经找到了一种合理的方法,可以对多种类型进行此操作

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

啊!!现在我意识到我的困惑。我在尝试包装的方法,但是我的业务逻辑被捆绑在返回
CoursePhoto
的范围内,但是有两个
JsonFormat[CoursePhoto]
。令人尴尬的是,我没有想到简单地创建一个
CoursePhotoMember
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")
  }
}