Scala 如何在PlayFramework中验证查询字符串参数

Scala 如何在PlayFramework中验证查询字符串参数,scala,playframework,playframework-2.3,Scala,Playframework,Playframework 2.3,我想知道,如何在PlayFramework 2.x中验证查询字符串参数。 假设我有非常常见的序列移位、限制(DROP、limit)参数,我有 这样的路线: # http://example.com/users?shift=0&limit=20 - take first 20 users GET /users Users.list(shift: Int ?= 0, limit: Int ?= 20) 我想让我的移位和限制保持在正确的范围内,例如限制从1到60,如果用

我想知道,如何在PlayFramework 2.x中验证查询字符串参数。 假设我有非常常见的序列移位、限制(DROP、limit)参数,我有 这样的路线:

# http://example.com/users?shift=0&limit=20 - take first 20 users
GET    /users         Users.list(shift: Int ?= 0, limit: Int ?= 20)
我想让我的移位和限制保持在正确的范围内,例如限制从1到60,如果用户试图设置限制,如23979,它应该减少到60。
过滤器对此不起作用,因为它们在路由器之后触发。

您可以在控制器
用户列表(shift:Int,limit:Int)中检查约束条件。
。然后,您可以使用自定义值重定向,而不是抛出异常。例如,
if(limit>60)重定向(routes.controllers.Users.list(shift,60))
我很喜欢biesor的评论,您可以在开始操作时验证它。如果这是不可能的,kfer38的答案也适用。我想抛出另一个答案,那就是使用全局对象

与重定向相比,全局对象的优势在于它可以立即执行,并且可以重新配置路由器,而不是重定向会增加运行时间毫秒。因为在路由器接触它们之前做一些事情似乎是一个问题,所以我提供了这个解决方案

类似这样的方法会奏效:

object Global extends GlobalSettings {
  override def onRouteRequest(request: RequestHeader): Option[Handler] = {
    // string matching here to get the values
    // rewrite values to what you want
    super.onRouteRequest(request.copy(path = newPath))
  }
}
例如,我使用它来删除路由末尾的“/”而不是重定向,这是非常低效的。我这样做也是为了避免仅仅为了匹配结尾“/”而写两倍的路由。

这种方法很好,但也有一些有趣的事情。 如果我过滤覆盖OnRouterRequest的查询参数,它过滤传递给操作函数的参数,但不过滤请求对象中的查询字符串参数:

def用户(shift:Int,limit:Int)=操作{req=>
Logger.debug(“shift:+shift”)
Logger.debug(“shiftQS:+req.getQueryString(“shift”))
如果我们请求
/users?shift=-2
我们的班次将被过滤,而shiftQS不会!但是如果您只使用
过滤器,情况似乎有所不同,它可以过滤查询字符串参数,但不能过滤您的参数。所以,要过滤查询字符串,您应该添加Play的
过滤器是:

# http://example.com/users?shift=0&limit=20 - take first 20 users
GET    /users         Users.list(shift: Int ?= 0, limit: Int ?= 20)
//编写过滤器并将其混合到全局
对象SeqFilter扩展了EssentialFilter{
def应用(下一步:EssentialAction):EssentialAction=新EssentialAction{
def apply(请求:RequestHeader):迭代对象[数组[字节],SimpleResult]={
下一步(doFilter(req))
}
}
def doFilter(请求:请求标头):请求标头={
如果(/*queryString包含无效参数*/){
val qs=/*您已筛选查询字符串*/
请求副本(queryString=qs)
}否则{
请求
}
}
}
//Alson在全局对象的onRouteRequest中使用过滤器
覆盖def OnRouterRequest(请求:RequestHeader):选项[Handler]={
super.onroutereRequest(SeqFilter.doFilter(请求))
}

只需在操作开始时验证它,您就可以创建一个简单的方法来验证param是否为数字以及它是否符合要求的范围,这样您还可以捕获用户将在其中插入一些字符串值的情况