考虑一个可以返回两个json作为响应的http服务:
成功
if (isset($_POST['sessName']) ){
$session_name = $_POST['sessName']
//output to console.log in case the variable is set
echo 'Session Variable : '.$session_name;
}else{
//output to console.log when variable is not set
echo 'Session Variable is not Set'; // if not
}
失败
{
"yourField":"value"
}
为了处理这些json,我需要创建2个案例类{
"errorCode": 3
}
和
case class RespSucc(yourField:String)
。
现在我必须这样:
case class RespFail(errorCode:Int)
是否有api在没有任何//unmarshal is spray.httpx.ResponseTransformation#unmarshal
if (response.entity.asString.contains("errorCode")) {
unmarshal[RespSucc].apply(response)
}
else {
unmarshal[RespFail].apply(response)
}
的情况下自动解析这些类?例如。 unmarshaller可以查看json字段并选择适当的案例类吗?
答案 0 :(得分:2)
spray-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))
答案 1 :(得分: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))