2017-02-12 6 views
0

die den folgenden Code Nehmen wir an:akka http (un) marshall traits

sealed trait Action { 
    def run(): Boolean 
} 

case class SimpleAction(parameter: String) extends Actions { 
// some impl 
} 

case class ExtendedAction(parameter1: String, parameter2: String) extends Actions { 
// some impl 
} 

Jetzt habe ich eine Webservice definieren möchten, wo man die Aktionen abrufen können. Wie kann ich die Action marshallieren, da es nur ein Merkmal und kein spezifischer Typ ist?

Ich habe diese https://github.com/spray/spray-json#providing-jsonformats-for-other-types in den Docs gefunden. Gibt es einen einfacheren Weg dies zu erreichen, als diesen Ansatz in Kombination mit dem Mustervergleich zu verwenden?

Antwort

1
import spray.json._ 
import DefaultJsonProtocol._ 

implicit val simpleActionFormat = jsonFormat1(SimpleAction) 
implicit val extendedActionFormat = jsonFormat2(ExtendedAction) 
implicit val actionFormat1 = new JsonFormat[Action] { 
    override def write(obj: Action): JsValue = obj match { 
    case a: SimpleAction => JsObject("type" -> "simple".toJson, "value" -> a.toJson) 
    case b: ExtendedAction => JsObject("type" -> "extended".toJson, "value" -> b.toJson) 
    } 

    override def read(json: JsValue): Action = json.asJsObject.getFields("type", "value") match { 
    case Seq(JsString("simple"), js) => js.convertTo[SimpleAction] 
    case Seq(JsString("extended"), js) => js.convertTo[ExtendedAction] 
    case _ => throw new RuntimeException(s"Invalid json format: $json") 
    } 
} 

Oder wenn Sie kümmern sich nur um Actions zu json Umwandlung, dann einfach:

implicit val simpleActionFormat = jsonFormat1(SimpleAction) 
implicit val extendedActionFormat = jsonFormat2(ExtendedAction) 
implicit val actionFormat = lift(new JsonWriter[Action] { 
    override def write(obj: Action): JsValue = obj match { 
    case a: SimpleAction => a.toJson 
    case b: ExtendedAction => b.toJson 
    } 
})