Play Framework 2.2.1 /控制器应该如何处理JSON格式的queryString

时间:2014-02-06 18:26:13

标签: json scala playframework-2.0 playframework-2.2

我的客户端在JSON对象中执行包含数据(queryString)的服务器调用,如下所示:

?q={"title":"Hello"}   //non encoded for the sample but using JSON.stringify actually

检索titleHello字符串的有效方法是什么?

我试过了:

val params = request.queryString.map {case(k,v) => k->v.headOption}

返回Tuple(q,Some({"title":"hello"}))

我可以进一步提取以检索值(虽然我需要手动将JSON对象映射到Scala对象),但我想知道是否有更简单和更短的方式。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

首先,如果您打算仅从请求中提取q参数而不打算通过route执行此操作,则可以直接抓取它:

val q: Option[String] = request.getQueryString("q")

接下来,您必须将其解析为JSON对象:

import play.api.libs.json._
val jsonObject: Option[JsValue] = q.map(raw: String => json.parse(raw))

,你应该能够检查jsonObject包含的组件:

val title: Option[String] = jsonObject.flatMap { json: JsValue =>
  (json \ "title").asOpt[String]
}

简而言之,省略类型,你可以用它来理解整个事情:

val title = for {
  q <- request.getQueryString("q")
  json <- Try(Json.parse(q)).toOption
  titleValue <- (json \ "title").asOpt[String]
} yield titleValue

Tryscala.util中定义,基本上捕获异常并以可处理的形式包装它。

我必须承认,在解析原始JSON字符串期间,最后一个版本只是忽略了异常,并将它们视为“没有设置标题查询”。 这不是了解实际出错的最佳方式。

在我们的高效代码中,我们使用隐式快捷方式将NoneJsError包装为Failure

val title: Try[String] = for {
  q <- request.getQueryString("q") orFailWithMessage "Query not defined"
  json <- Try(Json.parse(q))
  titleValue <- (json \ "title").validate[String].asTry
} yield titleValue

留在Try monad,我们会获得有关出错的信息,并可以将其提供给用户。

orFailWithMessage基本上是Option的隐式包装器,会使用指定的消息将其转换为SucccessFailure

JsResult.asTry也只是pimped JsResult,也是SuccessFailure