Come gestire i parametri di query opzionali nel quadro di riproduzione
-
11-12-2019 - |
Domanda
Diciamo che ho già una applicazione basata su struttura PLAY 2.0 già funzionante in Scala che serve un URL come:
http:// localhost: 9000 / compleanni
che risponde con un elenco di tutti i compleanni noti
Ora voglio migliorarlo aggiungendo la possibilità di limitare i risultati con optional "da" (data) e "a" richiedono parametri come
http:// localhost: 9000 / compleanni? da= 20120131 e amp; a= 20120229
(date qui interpretato come yyyymmdd)
La mia domanda è come gestire il legame e l'interpretazione dei parametri di richiesta in PLAY 2.0 con Scala, soprattutto dato che entrambi questi parametri dovrebbero essere opzionali.
Se questi parametri dovrebbero essere in qualche modo espressi nelle specifiche "percorsi"?In alternativa, se il metodo di risposta controller rispondesse a parte i parametri dall'oggetto di richiesta in qualche modo?C'è un altro modo per farlo?
Soluzione
Codifica i parametri facoltativi come Option[String]
(o Option[java.util.Date]
, ma dovrai implementare il proprio QueryStringBindable[Date]
):
def birthdays(from: Option[String], to: Option[String]) = Action {
// …
}
.
e dichiarare il seguente percorso:
GET /birthday controllers.Application.birthday(from: Option[String], to: Option[String])
. Altri suggerimenti
Un modo forse meno pulito per farlo per gli utenti Java sta impostando i valori predefiniti:
GET /users controllers.Application.users(max:java.lang.Integer ?= 50, page:java.lang.Integer ?= 0)
.
e nel controller
public static Result users(Integer max, Integer page) {...}
.
Un altro problema, dovrai ripetere i valori predefiniti ogni volta che si collega alla tua pagina nel modello
@routes.Application.users(max = 50, page = 0)
. Oltre alla risposta di Julien.Se non vuoi includerlo nel file rotte .
È possibile ottenere questo attributo nel metodo del controller utilizzando RequestHeader
.
String from = request().getQueryString("from");
String to = request().getQueryString("to");
Questo ti fornirà i parametri di richiesta desiderati, oltre a mantenere i tuoi itinerari puliti.
Ecco l'esempio di Julien ha riscritto in Java, usando f.Option: (funziona come di gioco 2.1)
import play.libs.F.Option;
public static Result birthdays(Option<String> from, Option<String> to) {
// …
}
.
percorso:
GET /birthday controllers.Application.birthday(from: play.libs.F.Option[String], to: play.libs.F.Option[String])
.
Puoi anche semplicemente scegliere i parametri di query arbitraria fuori come stringhe (devi fare la conversione del tipo):
public static Result birthdays(Option<String> from, Option<String> to) {
String blarg = request().getQueryString("blarg"); // null if not in URL
// …
}
. Per i parametri di query opzionali, puoi farlo in questo modo
Nel file percorsi, dichiarare API
GET /birthdays controllers.Application.method(from: Long, to: Long)
.
È inoltre possibile fornire un valore predefinito, nel caso in cui API non contenga questi parametri di query, assegnerà automaticamente i valori predefiniti a questi parametri
GET /birthdays controllers.Application.method(from: Long ?= 0, to: Long ?= 10)
.
In Metodo scritto all'interno dell'applicazione del controller Questi parametri avranno valore null
se nessun valore predefinito assegnato al altro valore predefinito.
Il mio modo di farlo coinvolge usando un QueryStringBindable
personalizzato.In questo modo esprimere i parametri in routine come:
GET /birthdays/ controllers.Birthdays.getBirthdays(period: util.Period)
.
Il codice per il periodo sembra questo.
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
è solo un metodo di convinzione che uso nei miei controller se voglio applicare la data filtraggio alla query.Ovviamente è possibile utilizzare altre predefiniture della data qui o utilizzare altri predefiniti rispetto a NULL per la data di inizio e di fine nel metodo bind
.