How to handle optional query parameters in Play framework

后端 未结 6 1565
礼貌的吻别
礼貌的吻别 2020-12-07 22:28

Lets say I have an already functioning Play 2.0 framework based application in Scala that serves a URL such as:

http://localhost:9000/birthdays

which respond

相关标签:
6条回答
  • 2020-12-07 22:50

    A maybe less clean way of doing this for java users is setting defaults:

    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)
    
    0 讨论(0)
  • 2020-12-07 22:51

    In Addition to Julien's answer. If you don't want to include it in the routes file.

    You can get this attribute in the controller method using RequestHeader

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

    This will give you the desired request parameters, plus keep your routes file clean.

    0 讨论(0)
  • 2020-12-07 23:00

    Here's Julien's example rewritten in java, using F.Option: (works as of 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
      // …
    }
    
    0 讨论(0)
  • 2020-12-07 23:03

    My way of doing this involves using a custom QueryStringBindable. This way I express parameters in routes as:

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

    The code for Period looks like this.

    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 is 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 bind method.

    0 讨论(0)
  • 2020-12-07 23:08

    For optional Query parameters, you can do it this way

    In routes file, declare 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

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

    In method written inside controller Application these params will have value null if no default values assigned else default values.

    0 讨论(0)
  • 2020-12-07 23:12

    Encode your optional parameters as Option[String] (or Option[java.util.Date], but you’ll have to implement your own 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])
    
    0 讨论(0)
提交回复
热议问题