Nehmen wir an, ich habe eine bereits funktionierende Play 2.0-Framework-basierte Anwendung in Scala, die eine URL wie die folgende bereitstellt:
http: // localhost: 9000 / Geburtstage
die mit einer Auflistung aller bekannten Geburtstage antwortet
Ich möchte dies jetzt verbessern, indem ich die Möglichkeit hinzufüge, Ergebnisse mit optionalen "von" (Datum) und "bis" Anforderungsparametern wie z
http: // localhost: 9000 / geburtstage? von = 20120131 & bis = 20120229
(Daten hier interpretiert als JJJJMMTT)
Meine Frage ist, wie die Bindung und Interpretation von Anforderungsparametern in Play 2.0 mit Scala behandelt werden soll, insbesondere angesichts der Tatsache, dass beide Parameter optional sein sollten.
Sollten diese Parameter irgendwie in der "Routen" -Spezifikation ausgedrückt werden? Sollte die antwortende Controller-Methode alternativ die Parameter irgendwie vom Anforderungsobjekt trennen? Gibt es einen anderen Weg, dies zu tun?
quelle
GET /birthday controllers.Application.birthday(from: Option[String] ?= None, to: Option[String] ?= None)
GET /birthday controllers.Application.birthday(Option[from], Option[to])
Eine möglicherweise weniger saubere Methode für Java-Benutzer ist das Festlegen von Standardeinstellungen:
GET /users controllers.Application.users(max:java.lang.Integer ?= 50, page:java.lang.Integer ?= 0)
Und in der Steuerung
public static Result users(Integer max, Integer page) {...}
Ein weiteres Problem: Sie müssen die Standardeinstellungen wiederholen, wenn Sie auf Ihre Seite in der Vorlage verlinken
@routes.Application.users(max = 50, page = 0)
quelle
play.libs.F.Option
anstelle von ScalaOption
Zusätzlich zu Juliens Antwort. Wenn Sie es nicht in die Routendatei aufnehmen möchten .
Sie können dieses Attribut in der Controller-Methode mit RequestHeader abrufen
String from = request().getQueryString("from"); String to = request().getQueryString("to");
Dadurch erhalten Sie die gewünschten Anforderungsparameter und halten Ihre Routendatei sauber.
quelle
GET /url @com.mycompany.controllers.MyClass.fetchget()
und es kann die Route nicht findenHier ist Juliens Beispiel, das mit F.Option in Java umgeschrieben wurde: (funktioniert ab Spiel 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])
Sie können auch einfach beliebige Abfrageparameter als Zeichenfolgen auswählen (Sie müssen die Typkonvertierung selbst durchführen):
public static Result birthdays(Option<String> from, Option<String> to) { String blarg = request().getQueryString("blarg"); // null if not in URL // … }
quelle
Bei optionalen Abfrageparametern können Sie dies auf diese Weise tun
Deklarieren Sie in der Routendatei die API
GET /birthdays controllers.Application.method(from: Long, to: Long)
Sie können auch einen Standardwert angeben. Falls die API diese Abfrageparameter nicht enthält, werden diesen Parametern automatisch die Standardwerte zugewiesen
GET /birthdays controllers.Application.method(from: Long ?= 0, to: Long ?= 10)
In der in der Controller-Anwendung geschriebenen Methode haben diese Parameter einen Wert,
null
wenn keine Standardwerte zugewiesen sind, andernfalls Standardwerte.quelle
Meine Art, dies zu tun, beinhaltet die Verwendung eines Brauchs
QueryStringBindable
. Auf diese Weise drücke ich Parameter in Routen aus als:GET /birthdays/ controllers.Birthdays.getBirthdays(period: util.Period)
Der Code für Periode sieht so aus.
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
ist nur eine Convenience-Methode, die ich in meinen Controllern verwende, wenn ich die Datumsfilterung auf die Abfrage anwenden möchte. Natürlich können Sie hier auch andere Datumsstandards verwenden oder einen anderen Standard als null für das Start- und Enddatum in derbind
Methode verwenden.quelle