2017-02-12 62 views
0

假設下面的代碼:阿卡HTTP(UN)馬歇爾性狀

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 
} 

現在我要定義一個Web服務,人們可以檢索操作。我怎樣才能把這個行動當作特徵而不是特定的類型呢?

我在文檔中找到了這個https://github.com/spray/spray-json#providing-jsonformats-for-other-types。有沒有比使用這種方法混合模式匹配更簡單的方法來實現這一點?

回答

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

或者,如果你只關心轉換Actions爲JSON,後來乾脆:

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