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?

È stato utile?

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) + "&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 è 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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top