我希望能够为我的所有请求访问某些查询参数。示例查询类似于:
http://api.mysite.com/accounts/123?include=friends,photos
我希望能够访问逗号分隔的include
关系列表。
据我所知,以下内容不起作用,并将包含列表视为单个字符串:
// routes.txt
GET /accounts/:id controllers.AccountsController.get(id: Int, include: Seq[String])
这就是我目前的做法,但我希望有一种更清洁的方式。
// routes.txt
GET /accounts/:id controllers.AccountsController.get(id: Int, include: Option[String])
// AccountsController.scala
def get(id: Int, include: Option[String]) = Action {
// Convert the option to a set
val set = if (include.isDefined) include.get.split(",").toSet else Set()
}
答案 0 :(得分:4)
正确的方法(Play已经支持)将在查询字符串中使用重复的键值,即:
http://api.mysite.com/accounts/123?include=friends&include=photos
这会自动将Seq("friends", "photos")
绑定到该路由中的include
。这样做的好处是能够在键中使用逗号,并且与查询字符串参数的常见用法一致。
或者,您可以创建可以处理以逗号分隔的列表的自定义QueryStringBindable[List[String]]
。类似的东西:
object QueryStringBinders {
implicit def listBinder(key: String)(implicit stringBinder: QueryStringBindable[String]) = {
new QueryStringBindable[List[String]] {
override def bind(key: String, params: Map[String, Seq[String]]): Option[Either[String, List[String]]] =
stringBinder.bind(key, params).map(_.right.map(_.split(",").toList))
override def unbind(key: String, strings: List[String]): String =
s"""$key=${strings.mkString(",")}"""
}
}
}
然后,您将在build.sbt中使用PlayKeys.routesImport += "QueryStringBinders._"
来使用它(或任何完全限定的包名称)。使用QueryStringBindable
可以使拆分逻辑重复使用,只需极少的样板。
答案 1 :(得分:0)
正如,@ m-z所说的正确使用方法是在查询字符串中重复键值,如:http://api.mysite.com/accounts/123?include=friends&include=photos
在您的操作中,您也可以使用queryString
方法访问查询字符串,即
您的路线将如下所示:
GET /accounts/:id controllers.AccountsController.get(id: Int)
并在您的控制器中:
// AccountsController.scala
def get(id: Int) = Action { request =>
// the `request.queryString` will give you Map[String, Seq[String]] i.e all they keys and their values
val includes = request.queryString.getOrElse("include", Nil)
}