首页 文章

如何在Play框架中处理可选的查询参数

提问于
浏览
63

假设我在Scala中已经运行了一个基于Play 2.0框架的应用程序,它可以提供以下URL:

http://localhost:9000/birthdays

它以所有已知生日的列表作出回应

我现在想通过添加使用可选的“from”(日期)和“to”请求参数限制结果的功能来增强此功能,例如

http://localhost:9000/birthdays?from=20120131&to=20120229

(此处的日期解释为yyyyMMdd)

我的问题是如何使用Scala处理Play 2.0中的请求参数绑定和解释,特别是考虑到这两个参数都应该是可选的 .

这些参数应该以某种方式在“路线”规范中表达吗?或者,响应的Controller方法应该以某种方式从请求对象中分离出params吗?还有另一种方法吗?

6 回答

  • 7

    将可选参数编码为 Option[String] (或 Option[java.util.Date] ,但您必须实现自己的 QueryStringBindable[Date] ):

    def birthdays(from: Option[String], to: Option[String]) = Action {
      // …
    }
    

    并声明以下路线:

    GET   /birthday       controllers.Application.birthday(from: Option[String], to: Option[String])
    
  • 4

    为Java用户执行此操作可能不太简洁的方法是设置默认值:

    GET  /users  controllers.Application.users(max:java.lang.Integer ?= 50, page:java.lang.Integer ?= 0)
    

    并在控制器中

    public static Result users(Integer max, Integer page) {...}
    

    还有一个问题,每当您链接到模板中的页面时,您都必须重复默认值

    @routes.Application.users(max = 50, page = 0)
    
  • 17

    除了Julien 's answer. If you don' t想要将它包含在路径文件中 .

    您可以使用RequestHeader在控制器方法中获取此属性

    String from = request().getQueryString("from");
    String to = request().getQueryString("to");
    

    这将为您提供所需的请求参数,并保持路由文件清洁 .

  • 8

    这里是朱利安用java重写的例子,使用F.Option :(作为播放2.1)

    import play.libs.F.Option;
    public static Result birthdays(Option<String> from, Option<String> to) {
      // …
    }
    

    路线:

    GET   /birthday       controllers.Application.birthday(from: play.libs.F.Option[String], to: play.libs.F.Option[String])
    

    您也可以选择任意查询参数作为字符串(您必须自己进行类型转换):

    public static Result birthdays(Option<String> from, Option<String> to) {
      String blarg = request().getQueryString("blarg"); // null if not in URL
      // …
    }
    
  • 2

    对于可选的Query参数,您可以这样做

    在routes文件中,声明API

    GET   /birthdays     controllers.Application.method(from: Long, to: Long)
    

    您还可以给出一些默认值,如果API不包含这些查询参数,它会自动为这些参数分配默认值

    GET   /birthdays    controllers.Application.method(from: Long ?= 0, to: Long ?= 10)
    

    在控制器内部编写的方法中,如果没有为默认值分配默认值,这些参数将具有值 null .

  • 54

    我这样做的方法是使用自定义 QueryStringBindable . 这样我在路线中表达参数:

    GET /birthdays/ controllers.Birthdays.getBirthdays(period: util.Period)
    

    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) + "&amp;" + "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());
      }
    
    }
    

    如果我想对查询应用日期过滤, applyDateFilter 只是我在控制器中使用的一种便利方法 . 显然,您可以在此处使用其他日期默认值,或者在 bind 方法中使用除null之外的其他默认值作为开始日期和结束日期 .

相关问题