Как обрабатывать необязательные параметры запроса в платформе Play

StackOverflow https://stackoverflow.com//questions/9657163

Вопрос

Допустим, у меня есть уже функционирующее приложение на базе платформы Play 2.0 в Scala, которое обслуживает такой URL-адрес:

http://localhost:9000/дни рождения

который отвечает списком всех известных дней рождения

Теперь я хочу улучшить это, добавив возможность ограничивать результаты с помощью дополнительных параметров запроса «от» (дата) и «до», таких как

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

(здесь даты интерпретируются как ггггММдд)

Мой вопрос заключается в том, как обрабатывать привязку и интерпретацию параметров запроса в Play 2.0 с помощью Scala, особенно с учетом того, что оба этих параметра должны быть необязательными.

Должны ли эти параметры быть каким-то образом выражены в спецификации «маршрутов»?В качестве альтернативы, должен ли отвечающий метод контроллера каким-то образом отделять параметры от объекта запроса?Есть ли другой способ сделать это?

Это было полезно?

Решение

Закодируйте свои дополнительные параметры как 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])

Другие советы

Возможно, менее чистый способ выполнения этого для пользователей 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)
.

В дополнение к ответу Джульен.Если вы не хотите включить его в маршруты .

Вы можете получить этот атрибут в методе контроллера, используя requestever

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

Это даст вам желаемые параметры запроса, плюс держите ваши маршруты файл .

Вот пример Джульен, переписанный в Java, используя f.option: (работает как Play 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
  // …
}
.

Для дополнительных параметров запроса вы можете сделать это таким образом

в файле маршрутов, объявить API

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

Вы также можете дать некоторое значение по умолчанию, в случае, если API не содержит эти параметры запроса, он автоматически назначает значения по умолчанию для этих параметров

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

В способе написано Внутреннее приложение контроллера Эти слова будут иметь значение null, если значения по умолчанию не назначаются значения по умолчанию.

Мой способ сделать это включает в себя пользовательский генеракодицетагкод.Таким образом, я экспрессирую параметры в маршрутах как:

GET /birthdays/ controllers.Birthdays.getBirthdays(period: util.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());
  }

}
.

QueryStringBindable - это просто метод содействия, который я использую в моем контроллерах, если я хочу применить фильтрацию даты в запрос.Очевидно, что вы можете использовать другие данные по умолчанию здесь или использовать некоторые другие по умолчанию, чем NULL для начала и окончания даты окончания в методе applyDateFilter.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top