簡體   English   中英

帶有 Play 框架的 Scala Graph JSON

[英]Scala Graph JSON with Play Framework

我正在嘗試將 POST 請求傳遞給使用 Play 開發的 REST API! (2.5) 我想使用 Scala Graph 的對象(來自圖形核心依賴項)。 看起來該圖已經具有基於 Lift-json 的 JSON 序列化/反序列化方法,但我不確定如何將其“插入”到 Play Json 庫中。 到目前為止,我一直在使用隱式轉換器(使用 Reads/Writes 方法),但我想避免為圖形部分編寫自己的方法,因為它已經是庫本身的一部分。

例如,假設我有以下代碼:

import java.util.UUID
import scalax.collection.Graph

case class Task(
  id: UUID,
  status: String)

case class Stuff(
  id: UUID = UUID.randomUUID(),
  name: String,
  tasks: Option[Graph[Task, DiEdge]])

implicit val stuffWrites: Writes[Stuff] = (
    (JsPath \ "id").write[UUID] and
    (JsPath \ "name").write[String]
  )(unlift(Stuff.unapply))

implicit val stuffReads: Reads[Stuff] = (
    (JsPath \ "id").read[UUID] and
    (JsPath \ "name").read[String]
  )(Stuff.apply _)

implicit val taskWrite: Writes[Task] = (
    (JsPath \ "id").write[UUID] and
    (JsPath \ "status").write[String]
  )(unlift(Task.unapply))

implicit val taskReads: Reads[Task] = (
    (JsPath \ "id").read[UUID] and
    (JsPath \ "status").read[String]
  )(Task.apply _)

我錯過了序列化圖表和育兒的部分。 我應該從頭開始重寫所有內容,還是可以依賴 scalax.collection.io.json 中的 toJson/fromJson 方法?

由於我努力讓這個工作,我想我會分享代碼:

class UUIDSerializer extends Serializer[UUID] {
  private val UUIDClass = classOf[UUID]

  def deserialize(implicit format: Formats): PartialFunction[(TypeInfo, JValue), UUID] = {
    case (TypeInfo(UUIDClass, _), json) => json match {
      case JString(id) => UUID.fromString(id)
      case x => throw new MappingException("Can't convert " + x + " to UUID")
    }
  }
  def serialize(implicit format: Formats): PartialFunction[Any, JValue] = {
    case x: UUID => JString(x.toString)
  }
}

val extraSerializers = new UUIDSerializer :: Nil
implicit val formats = Serialization.formats(NoTypeHints) ++ extraSerializers

val taskDescriptor = new NodeDescriptor[Task](typeId = "Tasks", customSerializers=extraSerializers) {
  def id(node: Any) = node match {
    case Task(id, _) => id.toString
  }
}

val quickJson = new Descriptor[Task](
    defaultNodeDescriptor = taskDescriptor,
    defaultEdgeDescriptor = Di.descriptor[Task]()
)
implicit val tasksWrites = new Writes[Graph[Task, DiEdge]] {
  def writes(graph: Graph[Task, DiEdge]): JsValue = {
    val json = graph.toJson(quickJson)
    Json.parse(json.toString)
  }
}

implicit val tasksReads = new Reads[Graph[Task, DiEdge]] {
  def reads(json: JsValue): JsResult[Graph[Task, DiEdge]] = {
    try {
      val graph = Graph.fromJson[Task, DiEdge](json.toString, quickJson)
      JsSuccess(graph)
    }
    catch {
      case e: Exception =>
        JsError(e.toString)
    }
  }
}

implicit def stuffModelFormat = Jsonx.formatCaseClass[Stuff]

您可以嘗試為您指定格式的案例類編寫配套對象。

例子:

object Task {
  implicit val taskModelFormat = Json.format[Task]
}

object Stuff {
  implicit val staffModelFormat = Json.format[Stuff]
}

而不是上面的implicits 使用此解決方案,編譯器將為您解析已知的格式化程序,您可能只需要指定缺失/未知類型而不是整個結構。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM