【问题标题】:how to define optional path parameters in Play Framework routes如何在 Play Framework 路由中定义可选路径参数
【发布时间】:2016-01-19 21:11:14
【问题描述】:

我有以下重载函数来匹配我的路由文件

  def getMessage() = getMessage(None, None, None)
  def getMessage(campaignID: Option[String]) = getMessage(campaignID, None, None)
  def getMessage(campaignID: Option[String], revision: Option[Int]) = getMessage(campaignID, revision, None)
  def getMessage(campaignID: Option[String], revision: Option[Int], transactionID: Option[Int] ) = Action.async { implicit request =>

    db.getDocument(campaignID, revision, transactionID)
    .map(result =>
    Ok(Json.toJson(result))).recover {case ex: IOException => InternalServerError("Please install MongoDB")}
  }

这是我的路线文件:

GET     /message                                                          controllers.Application.getMessage()
GET     /message/:campaignID                                              controllers.Application.getMessage(campaignID:String)
GET     /message/:campaignID/:revision                                    controllers.Application.getMessage(campaignID:String, revision:Int)
GET     /message/:campaignID/:revision/:transactionID                     controllers.Application.getMessage(campaignID:String, revision:Int, transactionID:Int)

如何使其工作,以便在 REST 调用中完全可以选择campaignID、revision 和transactionID?现在,我收到以下错误:

[error] /Users/superman/conf/routes:9: Compilation error[Using different overloaded methods is not allowed. If you are using a single method in combination with default parameters, make sure you declare them all explicitly.]
[error] GET     /message/:campaignID                                              controllers.Application.getMessage(campaignID:String)
[error]                                                                           ^
[error] (compile:playRoutes) @6oo852mf7: Compilation error in /Users/superman/conf/routes:9
[error] - application - 

! @6oo852mf7 - Internal server error, for (GET) [/message/A/1/124] ->

play.sbt.routes.RoutesCompilationException: Compilation error[Using different overloaded methods is not allowed. If you are using a single method in combination with default parameters, make sure you declare them all explicitly.]
        at play.sbt.routes.RoutesCompiler$$anonfun$9.apply(RoutesCompiler.scala:152) ~[na:na]
        at play.sbt.routes.RoutesCompiler$$anonfun$9.apply(RoutesCompiler.scala:150) ~[na:na]
        at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) ~[scala-library-2.11.6.jar:na]
        at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) ~[scala-library-2.11.6.jar:na]
        at scala.collection.immutable.List.foreach(List.scala:318) ~[scala-library-2.11.6.jar:na]
        at scala.collection.TraversableLike$class.map(TraversableLike.scala:244) ~[scala-library-2.11.6.jar:na]
        at scala.collection.AbstractTraversable.map(Traversable.scala:105) ~[scala-library-2.11.6.jar:na]
        at play.sbt.routes.RoutesCompiler$.compileRoutes(RoutesCompiler.scala:150) ~[na:na]
        at play.sbt.routes.RoutesCompiler$$anonfun$4.apply(RoutesCompiler.scala:127) ~[na:na]
        at play.sbt.routes.RoutesCompiler$$anonfun$4.apply(RoutesCompiler.scala:126) ~[na:na]
        at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47) ~[scala-library-2.11.6.jar:na]
        at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:40) ~[na:na]
        at sbt.std.Transform$$anon$4.work(System.scala:63) ~[na:na]
        at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226) ~[na:na]
        at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226) ~[na:na]
        at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17) ~[na:na]
        at sbt.Execute.work(Execute.scala:235) ~[na:na]
        at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226) ~[na:na]
        at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226) ~[na:na]
        at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:159) ~[na:na]
        at sbt.CompletionService$$anon$2.call(CompletionService.scala:28) ~[na:na]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_60]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_60]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_60]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_60]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_60]
        at java.lang.Thread.run(Thread.java:745) [na:1.8.0_60]

【问题讨论】:

  • 你可以给GET请求中没有给出的参数一个默认值,你知道吗? Play 不支持该选项作为路由文件中的参数。
  • 只能有可选的查询字符串参数,不能有可选的路径参数。

标签: scala playframework routes


【解决方案1】:

您的控制器中只需要一个方法,如下所示:

package controllers

import play.api.mvc._

class Application extends Controller {

  def options(id:Long, revision: Int, transaction: Int) = Action {
    Ok(views.html.index(s"id: $id, revision: $revision, transaction: $transaction"))
  }
}

然后你可以像这样声明你的路线:

GET     /options                              controllers.Application.options(id:Long = 1, revision:Int = 2, transaction:Int = 3)
GET     /options/:id                          controllers.Application.options(id:Long, revision:Int = 2, transaction:Int = 3)
GET     /options/:id/:revision                controllers.Application.options(id:Long, revision:Int, transaction:Int = 3)
GET     /options/:id/:revision/:transaction   controllers.Application.options(id:Long, revision:Int, transaction:Int)

【讨论】:

  • 谢谢!但对我来说,这些默认值也是问题,因为我必须根据这些字段(id、修订、事务)查询 mondoDB。拥有默认值意味着我的查询可能会产生不同的结果。
【解决方案2】:

您不需要在路由文件中定义 3 个条目。只需一个具有以下给定签名的条目:

controllers.Application.options(id:Option[Long], revision:Option[Int], transaction:Option[Int])

在控制器中,只需像这样使用id.isDefined, revision.isDefined, transaction.isDefined 检查所有 3 个。然后您可以使用 .get 方法获取值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-11
    • 2021-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-07
    • 1970-01-01
    相关资源
    最近更新 更多