2015-08-25 30 views
0

考慮一個HTTP服務,可以返回兩個JSON作爲響應:如何在噴霧中編組不同的響應類型?

成功

​​

失敗

{ 
    "errorCode": 3 
} 

爲了解決這些JSON的,我需要創建2 case類case class RespSucc(yourField:String)case class RespFail(errorCode:Int)

現在我必須要這樣的事情:

//unmarshal is spray.httpx.ResponseTransformation#unmarshal 
if (response.entity.asString.contains("errorCode")) { 
    unmarshal[RespSucc].apply(response) 
} 
else { 
    unmarshal[RespFail].apply(response) 
} 

是否有一個API來自動解析這些類沒有任何if?例如。 unmarshaller可以查看json字段並選擇合適的case類嗎?

回答

0

你可以嘗試這樣的事情:

trait Resp 
case class RespSucc(yourField: String) extends Resp 
case class RespFail(errorCode: Int) extends Resp 

object MyJsonProtocol extends DefaultJsonProtocol { 
    implicit object ColorJsonFormat extends RootJsonFormat[Resp] { 
    def write(r: Resp) = r match { 
     case s: RespSucc => 
     JsObject("yourField" -> JsString(s.yourField)) 
     case f: RespFail => 
     JsObject("errorCode" -> JsNumber(f.errorCode)) 
    } 

    def read(value: JsValue) = value.asJsObject.getFields("yourField", "errorCode") match { 
     case Seq(JsString(yourField)) => RespSucc(yourField) 
     case Seq(JsNumber(errorCode)) => RespFail(errorCode.intValue()) 
     case _ => deserializationError("Resp expected") 
    } 
    } 
} 

import MyJsonProtocol._ 

unmarshal[Resp](entitySucc) //Right(RespSucc(abc)) 

unmarshal[Resp](entityFail) //Right(RespFail(3)) 
1

噴霧JSON支持Either這是這種情況下,一個非常有用的數據類型。

val data = unmarshal[Either[RespFail, RespSucc]].apply(response) 

// You can match it 
data match { 
    case Left(err) => handleError(err) 
    case Right(suc) => handleSuccess(suc) 
} 

// Or you can fold it (I prefer folding) 
data.fold(err => handleError(err), suc => handleSuccess(suc))