Comment gérer l'option paramètres de la requête dans le Jeu-cadre
-
11-12-2019 - |
Question
Disons que j'ai déjà le fonctionnement de Jouer 2.0 cadre de l'application de la Scala qui sert une URL de la forme:
http://localhost:9000/birthdays
qui répond avec une liste de tous les anniversaires
Je veux m'améliorer en ajoutant la possibilité de restreindre les résultats avec l'option "à partir de" (date) et "à" la demande de paramètres tels que
http://localhost:9000/birthdays?from=20120131&to=20120229
(les dates ici interprété comme aaaammjj)
Ma question est de savoir comment gérer la demande param de liaison et d'interprétation dans le Jeu 2.0 avec Scala, en particulier étant donné que deux de ces paramètres devrait être facultatif.
Si ces paramètres sont quelque peu exprimé dans les "routes" cahier des charges?Alternativement, si la réponse du Contrôleur de la méthode de sélection à part les paramètres de l'objet de la requête en quelque sorte?Est-il une autre façon de le faire?
La solution
L'encodage de vos paramètres facultatifs, comme Option[String]
(ou Option[java.util.Date]
, mais vous aurez à mettre en place votre propre QueryStringBindable[Date]
):
def birthdays(from: Option[String], to: Option[String]) = Action {
// …
}
Et de déclarer le parcours suivant:
GET /birthday controllers.Application.birthday(from: Option[String], to: Option[String])
Autres conseils
Un moyen moins propre de faire cela pour les utilisateurs Java est défini par défaut:
GET /users controllers.Application.users(max:java.lang.Integer ?= 50, page:java.lang.Integer ?= 0)
et dans le contrôleur
public static Result users(Integer max, Integer page) {...}
Un autre problème, vous devrez répéter les valeurs par défaut chaque fois que vous liez sur votre page dans le modèle
@routes.Application.users(max = 50, page = 0)
En plus de la réponse de Julien.Si vous ne voulez pas l'inclure dans le fichier itinéraires .
Vous pouvez obtenir cet attribut dans la méthode du contrôleur à l'aide de requestheader
String from = request().getQueryString("from");
String to = request().getQueryString("to");
Ceci vous donnera les paramètres de la demande souhaitée, plus Gardez votre itinéraires propre.
Voici l'exemple de Julien réécrit en Java, en utilisant F.Option: (fonctionne comme de la lecture 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])
Vous pouvez également choisir des paramètres de requête arbitraires en tant que chaînes (vous devez faire la conversion de type vous-même):
public static Result birthdays(Option<String> from, Option<String> to) {
String blarg = request().getQueryString("blarg"); // null if not in URL
// …
}
Pour les paramètres de requête optionnels, vous pouvez le faire de cette façon
dans le fichier de routes, déclarez API
GET /birthdays controllers.Application.method(from: Long, to: Long)
Vous pouvez également donner une valeur par défaut, au cas où API ne contient pas ces paramètres de requête, il affectera automatiquement les valeurs par défaut à ces params
GET /birthdays controllers.Application.method(from: Long ?= 0, to: Long ?= 10)
Dans la méthode écrite à l'intérieur de l'application Contrôleur Ces paramètres seront de valeur null
si aucune valeur par défaut n'est attribuée aux valeurs d'autre par défaut.
Ma façon de le faire consiste à utiliser un custom QueryStringBindable
.De cette façon, j'exprime des paramètres dans les itinéraires:
GET /birthdays/ controllers.Birthdays.getBirthdays(period: util.Period)
Le code pour la Période qui ressemble à ça.
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());
}
}
applyDateFilter
est juste un convienence méthode que j'utilise dans mes contrôleurs si je veux appliquer le filtrage par date de la requête.Évidemment, vous pouvez utiliser d'autres date par défaut ici, ou utilisez une autre défaut que la valeur null pour le début et date de fin dans le bind
la méthode.