0

私は RESTful インターフェイスを作成しています。JSON をマーシャリングおよびアンマーシャリングして Ember Data に対応させたいと考えています。問題は、Ember Data がエンティティ名を必要としており、私が試した 2 つのライブラリ、spray-json と json4s は、これを簡単に実行できないように見えることです。

必要なEmber データ形式

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

私がScalaでSprayで書いていることを考えると、名前付きルートのJSON出力を取得する良い方法は何ですか? 私は、Spray と適切に統合され、適度にパフォーマンスの高い JSON ライブラリでこれを行うことができて非常に満足しています。

4

2 に答える 2

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")
  }
}
于 2014-06-08T14:20:50.213 に答える