scala 如何在 Play 框架中处理可选的查询参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9657163/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to handle optional query parameters in Play framework
提问by magicduncan
Lets say I have an already functioning Play 2.0 framework based application in Scala that serves a URL such as:
假设我在 Scala 中有一个已经运行的基于 Play 2.0 框架的应用程序,它提供一个 URL,例如:
http://localhost:9000/birthdays
http://localhost:9000/birthdays
which responds with a listing of all known birthdays
它以所有已知生日的列表作为响应
I now want to enhance this by adding the ability to restrict results with optional "from" (date) and "to" request params such as
我现在想通过添加使用可选的“from”(日期)和“to”请求参数来限制结果的能力来增强这一点,例如
http://localhost:9000/birthdays?from=20120131&to=20120229
http://localhost:9000/birthdays?from=20120131&to=20120229
(dates here interpreted as yyyyMMdd)
(此处的日期解释为 yyyyMMdd)
My question is how to handle the request param binding and interpretation in Play 2.0 with Scala, especially given that both of these params should be optional.
我的问题是如何使用 Scala 处理 Play 2.0 中的请求参数绑定和解释,特别是考虑到这两个参数都应该是可选的。
Should these parameters be somehow expressed in the "routes" specification? Alternatively, should the responding Controller method pick apart the params from the request object somehow? Is there another way to do this?
这些参数是否应该在“路由”规范中以某种方式表达?或者,响应控制器方法是否应该以某种方式从请求对象中挑选参数?有没有其他方法可以做到这一点?
采纳答案by Julien Richard-Foy
Encode your optional parameters as Option[String](or Option[java.util.Date], but you'll have to implement your own QueryStringBindable[Date]):
将您的可选参数编码为Option[String](或Option[java.util.Date],但您必须实现自己的QueryStringBindable[Date]):
def birthdays(from: Option[String], to: Option[String]) = Action {
// …
}
And declare the following route:
并声明以下路线:
GET /birthday controllers.Application.birthday(from: Option[String], to: Option[String])
回答by Somatik
A maybe less clean way of doing this for java users is setting defaults:
对于 Java 用户来说,一种可能不太干净的方法是设置默认值:
GET /users controllers.Application.users(max:java.lang.Integer ?= 50, page:java.lang.Integer ?= 0)
And in the controller
并在控制器中
public static Result users(Integer max, Integer page) {...}
One more problem, you'll have to repeat the defaults whenever you link to your page in the template
还有一个问题,每当您链接到模板中的页面时,您都必须重复默认设置
@routes.Application.users(max = 50, page = 0)
回答by Dave Ranjan
In Addition to Julien's answer. If you don't want to include it in the routesfile.
除了朱利安的回答。如果您不想将其包含在路由文件中。
You can get this attribute in the controller method using RequestHeader
您可以使用 RequestHeader 在控制器方法中获取此属性
String from = request().getQueryString("from");
String to = request().getQueryString("to");
This will give you the desired request parameters, plus keep your routesfile clean.
这将为您提供所需的请求参数,并保持您的路由文件干净。
回答by Max
Here's Julien's example rewritten in java, using F.Option: (works as of play 2.1)
这是使用 F.Option 用 Java 重写的 Julien 示例:(从 play 2.1 开始工作)
import play.libs.F.Option;
public static Result birthdays(Option<String> from, Option<String> to) {
// …
}
Route:
路线:
GET /birthday controllers.Application.birthday(from: play.libs.F.Option[String], to: play.libs.F.Option[String])
You can also just pick arbitrary query parameters out as strings (you have to do the type conversion yourself):
您也可以将任意查询参数作为字符串挑选出来(您必须自己进行类型转换):
public static Result birthdays(Option<String> from, Option<String> to) {
String blarg = request().getQueryString("blarg"); // null if not in URL
// …
}
回答by Himanshu Goel
For optional Query parameters, you can do it this way
对于可选的 Query 参数,您可以这样做
In routes file, declare API
在路由文件中,声明 API
GET /birthdays controllers.Application.method(from: Long, to: Long)
You can also give some default value, in case API doesn't contain these query params it will automatically assign the default values to these params
您还可以提供一些默认值,如果 API 不包含这些查询参数,它会自动将默认值分配给这些参数
GET /birthdays controllers.Application.method(from: Long ?= 0, to: Long ?= 10)
In method written inside controller Application these params will have value nullif no default values assigned else default values.
在控制器应用程序内部编写的方法中,null如果没有分配其他默认值的默认值,这些参数将具有值。
回答by stian
My way of doing this involves using a custom QueryStringBindable. This way I express parameters in routes as:
我这样做的方法涉及使用自定义QueryStringBindable. 这样我将路由中的参数表示为:
GET /birthdays/ controllers.Birthdays.getBirthdays(period: util.Period)
The code for Period looks like this.
Period 的代码如下所示。
public class Period implements QueryStringBindable<Period> {
public static final String PATTERN = "dd.MM.yyyy";
public Date start;
public Date end;
@Override
public F.Option<Period> bind(String key, Map<String, String[]> data) {
SimpleDateFormat sdf = new SimpleDateFormat(PATTERN);
try {
start = data.containsKey("startDate")?sdf.parse(data.get("startDate") [0]):null;
end = data.containsKey("endDate")?sdf.parse(data.get("endDate")[0]):null;
} catch (ParseException ignored) {
return F.Option.None();
}
return F.Option.Some(this);
}
@Override
public String unbind(String key) {
SimpleDateFormat sdf = new SimpleDateFormat(PATTERN);
return "startDate=" + sdf.format(start) + "&" + "endDate=" + sdf.format(end);
}
@Override
public String javascriptUnbind() {
return null;
}
public void applyDateFilter(ExpressionList el) {
if (this.start != null)
el.ge("eventDate", this.start);
if (this.end != null)
el.le("eventDate", new DateTime(this.end.getTime()).plusDays(1).toDate());
}
}
applyDateFilteris just a convienence method i use in my controllers if I want to apply date filtering to the query. Obviously you could use other date defaults here, or use some other default than null for start and end date in the bindmethod.
applyDateFilter如果我想对查询应用日期过滤,这只是我在控制器中使用的一种方便方法。显然,您可以在此处使用其他日期默认值,或者在方法中使用除 null 以外的其他默认值作为开始和结束日期bind。

