查询参数为List

时间:2016-04-12 02:00:32

标签: scala playframework

我希望能够为我的所有请求访问某些查询参数。示例查询类似于:

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()

} 

2 个答案:

答案 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)
    }