Play& JSON转换:如何处理可选输入并处理可能的故障

时间:2014-02-05 21:47:56

标签: json scala playframework

以下find方法应返回符合指定选择条件的任何文档,并且如果按可选参数sort指定的方式对其进行排序:

class DaoComponent {

  ...

  val toObjectId = (__.json.update((__ \ '_id \ '$oid).json.copyFrom((__ \ 'id).json.pick))
    andThen (__ \ 'id).json.prune
  )

  ...

  def find(selector: JsValue, sort: Option[JsValue]): Future[Seq[A]] = {
    selector.transform(toObjectId).flatMap { s =>
    sort.map(_.transform((__ \ 'ignore).json.prune)).map { o =>

      // how do I get 'o' to be either None or Some(content of JsSuccess)?

      collection.find(s)
        .sort(o.getOrElse(Json.obj())
        .cursor[JsValue].collect[Vector](0)
    }.recoverTotal { errors =>
       Future.failed(JsError.toFlatJson(errors))
    }   
  }
}

在上面的代码中,让我们隔离我需要您宝贵支持的行:

sort.map(_.transform((__ \ 'ignore).json.prune)).map { o =>

可选参数sort必须仅在定义时进行转换...这是通过map实现的。现在问题是transform返回JsResult,我希望o在定义可选参数Some(jsValue)sorttransformNone成功,或transform失败时sort或未定义可选参数None

或者,在_.transform失败时获取recoverTotal,而不是在{{1}}块中处理失败,这将是很好的。

1 个答案:

答案 0 :(得分:1)

扩展我的评论 -

我认为flatMap和转换你的JsResult asOpt的正确组合将得到你想要的东西:

sort.flatMap(_.transform((__ \ 'ignore).json.prune).asOpt).map { o =>
  // Code in here only executed iff sort defined and transform succeeds
  ...
}

在我的测试中BTW在这种情况下实际上我无法让transform“失败” - 我认为如果给定的JSON不存在,prune是非常宽容的。我可以让它像这样适当地失败:

sort.flatMap(_.transform((__ \ 'ignore).json.pick).asOpt).map { o =>