【问题标题】:Play Framework 2.2.1 / How should controller handle a queryString in JSON formatPlay Framework 2.2.1 / 控制器应该如何处理 JSON 格式的 queryString
【发布时间】:2014-03-03 21:02:49
【问题描述】:

我的客户端在 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 对象),但我想知道是否有更简单和更短的方法。

有什么想法吗?

【问题讨论】:

  • 为什么不直接在请求正文中发布 JSON?
  • @Ryan 因为实际调用涉及按约定使用 GET 的“索引”Rest 方法。参数将允许过滤返回的结果。
  • @Ryan 实际上对于GET 是正确的,如果您打算从 RESTful 服务接收资源。 POST 不应用于此类请求。

标签: json scala playframework-2.0 playframework-2.2


【解决方案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]
}

简而言之,省略可以使用 for 理解的类型,如下所示:

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

Try 定义在scala.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

【讨论】:

  • 我目前正在写一个类似的解决方案,但我真的很喜欢你的 :) 非常感谢!
  • 我曾经使用带有Validation 机制的Scalaz 而不是Scala 的Try,但它也很有效:) ValidationOption 上也有一个包装器。
  • 是的,它们非常相似。在 2.10 之前,我们使用 Scalaz 正是为了这个目的,但决定放弃它,转而使用 Try
  • 我应该对 Scala 中的异常处理变体进行新的比较:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-18
  • 1970-01-01
  • 2015-04-06
  • 1970-01-01
  • 2013-09-16
  • 2014-03-22
  • 2017-06-13
相关资源
最近更新 更多