Json 播放ws如何以类型安全的方式映射响应

Json 播放ws如何以类型安全的方式映射响应,json,scala,serialization,playframework,Json,Scala,Serialization,Playframework,如何以类型安全的方式映射play ws async web请求的JSON响应 private def webRequest(): Map[String, Any] = { case class QuantileResult(val_05: Double, val_25: Double, val_50: Double, val_75: Double, val_90: Double) object QuantileResult { implicit val quant

如何以类型安全的方式映射play ws async web请求的JSON响应

private def webRequest(): Map[String, Any] = {

    case class QuantileResult(val_05: Double, val_25: Double, val_50: Double, val_75: Double, val_90: Double)

    object QuantileResult {
      implicit val quantileResultFormat = Json.format[QuantileResult]
    }

    implicit val quantileReads = Json.reads[QuantileResult]

    val payload = Json.obj(
      "json" -> Json.parse("""{"type":1,"x":[1,2,3,4,5,6,7,8,9,10],"probs":[0.05,0.25,0.75,0.95]}"""),
      "windowWidth" -> JsNumber(11)
    )

    wsClient.url("http://public.opencpu.org/ocpu/library/stats/R/quantile/json")
      .withHeaders("Content-Type" -> "application/json")
      .post(payload)
      .map { wsResponse =>
        if (!(200 to 299).contains(wsResponse.status)) {
          sys.error(s"Received unexpected status, open-cpu error ${wsResponse.status} : ${wsResponse.body}")
        }
        println(s"OK, received ${wsResponse.body}")
        wsResponse.json.validate[QuantileResult]
        match {
          case JsSuccess(arrOut: QuantileResult, _) => QuantileResult //TODO how to perform mapping here to Map[String, Any]
          case e: JsError => JsError.toFlatForm(e) // TODO empty array does not work here otherwise future[object] does not conform to expected return type of Map[String, Any]
        }
      }
  }
  • 如何在此处执行映射以映射[字符串,任意]
  • 空映射在此不起作用,否则future[object]不符合映射[String,Any]的预期返回类型
  • 有效的是

     wsClient.url("url").withHeaders("Content-Type" -> "application/json").post(payload).map { wsResponse => result = wsResponse.body }
    
            val json = Json.parse(result)
            val mapper = new ObjectMapper() with ScalaObjectMapper
            mapper.registerModule(DefaultScalaModule)
            val returnValue = mapper.readValue[Map[String, Any]](result)
    

    但这似乎非常笨拙,而且不是异步的。

    解决方案是将方法签名更改为适当的future
    future[Seq[Map[String,Any]]]
    并通过
    wait.result(someMethod),20秒)解决它。

    映射的执行方式如下所示

    wsResponse.json.validate[Seq[OutlierResult]] match {
              case JsSuccess(result, _) => result.map(outlierRes => Map("period" -> outlierRes.period, "amount" -> outlierRes.amount, "outlier" -> outlierRes.outlier))
              case JsError(error) => throw new OutlierParseException(error.toString())
            }
    

    即使这可以改进为不引发异常

    事实上,这并不是最佳解决方案,例如,异常处理得不好。但它是有效的。