有没有办法将可选查询参数添加到选定(或所有)操作,而无需在Controller中的操作定义期间显式指定它

时间:2016-09-26 15:26:00

标签: scala playframework

class Ctrl extends Controller {
  def action1(parameter: Option[Boolean]) = Action.async { implicit request =>
  ...

  def action2(parameter: Option[Boolean]) = Action.async { implicit request =>
  ...
}

有没有办法指明例如此Actions中定义的所有Ctrl都可以处理可选查询parameter

2 个答案:

答案 0 :(得分:1)

只需从每个操作的查询字符串中读取它:

request.queryString.get("param1").flatMap(_.headOption)

或创建一个阅读它的功能:

class ApplicationController extends ... {
   ...
   // define it once in the controller (or in a trait that the controller extends)
   def param1 (implicit r: RequestHeader): Option[String] = 
     request.queryString.get("param1").flatMap(_.headOption)
   ...


   def action1 () = Action.async {implicit request =>
     // use it here now
     param1 // Option[String]

     ...
   }
}

答案 1 :(得分:0)

是的,您可以使用

执行此操作
req.queryString.get(name).flatMap(_.headOption)

在每个操作中使用name获取查询参数,并根据可选参数创建输出。但是这种方法的问题是代码重复。你必须在每一个行动中都这样做。

有一种方法可以使用没有代码重复的Action合成来完成此操作。创建自定义操作,从请求的queryParams读取所需的参数。现在,您可以使用自定义操作来访问Option[String],如果用户已将其发送到请求网址中,那么这是一个参数。

QueryPramAction.scala

trait QueryParamAction {
  self: Controller =>

  def withQueryParamAction(f: Option[String] => Request[AnyContent] => Future[Result], name: String = "param") = Action.async { req =>
    f(req.queryString.get(name).flatMap(_.headOption))(req)
  }

}

ApplicationController.scala

class ApplicationController @Inject() () extends Controller with QueryParamAction {

  def doStuff = withQueryParamAction { paramOpt => req =>
    Future.successful(Ok(s"got a param $paramOpt"))
  }

}

路由

GET   /dostuff   controllers.ApplicationController.doStuff

请求

http://localhost:9000/dostuff?param=hello

输出

got a param Some(hello)

如果你不需要一个选项,如果你每次都需要一个参数,那么改变CustomParamAction特性的实现,如下所示

trait QueryParamAction {
  self: Controller =>

  def withQueryParam(f: String => Request[AnyContent] => Future[Result], name: String = "param") = Action.async { req =>
    req.queryString.get(name).flatMap(_.headOption).map(f(_)(req)).getOrElse(Future.successful(BadRequest(s"need a param with name: $name")))
  }

}

如果你没有在网址中发送参数

,那么你将获得BadRequest