【问题标题】:How to marshal different response types in spray?如何在喷雾中编组不同的响应类型?
【发布时间】:2015-08-25 16:10:04
【问题描述】:

考虑一个可以返回两个json作为响应的http服务:

成功

{
    "yourField":"value"
}

失败

{
    "errorCode": 3
}

为了处理这些 json,我需要创建 2 个案例类 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)
}

是否有无需任何if 即可自动解析这些类的api?例如。 unmarshaller 可以查看 json 字段并选择合适的案例类吗?

【问题讨论】:

    标签: json scala marshalling unmarshalling spray


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      你可以试试这样的:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多