如何在喷雾中编组不同的响应类型?

时间:2015-08-25 16:10:05

标签: json scala marshalling unmarshalling spray

考虑一个可以返回两个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字段并选择适当的案例类吗?

2 个答案:

答案 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))