我的客户端在JSON对象中执行包含数据(queryString)的服务器调用,如下所示:
?q={"title":"Hello"} //non encoded for the sample but using JSON.stringify actually
检索title
和Hello
字符串的有效方法是什么?
我试过了:
val params = request.queryString.map {case(k,v) => k->v.headOption}
返回Tuple
:(q,Some({"title":"hello"}))
我可以进一步提取以检索值(虽然我需要手动将JSON对象映射到Scala对象),但我想知道是否有更简单和更短的方式。
有什么想法吗?
答案 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
Try
在scala.util
中定义,基本上捕获异常并以可处理的形式包装它。
我必须承认,在解析原始JSON字符串期间,最后一个版本只是忽略了异常,并将它们视为“没有设置标题查询”。 这不是了解实际出错的最佳方式。
在我们的高效代码中,我们使用隐式快捷方式将None
和JsError
包装为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
的隐式包装器,会使用指定的消息将其转换为Succcess
或Failure
。
JsResult.asTry
也只是pimped JsResult,也是Success
或Failure
。