scala - programacion - Cómo manejar los parámetros de consulta opcionales en Play framework
manual de programacion android pdf (6)
Además de la respuesta de Julien. Si no desea incluirlo en el archivo de rutas.
Puede obtener este atributo en el método del controlador utilizando RequestHeader
String from=request().getQueryString("from");
String to=request().getQueryString("to");
Esto le dará los parámetros de solicitud deseados, además de mantener limpio el archivo de rutas.
Digamos que tengo una aplicación basada en el marco de Play 2.0 que ya funciona en Scala que sirve una URL como:
http://localhost:9000/birthdays
que responde con una lista de todos los cumpleaños conocidos
Ahora quiero mejorar esto al agregar la capacidad de restringir los resultados con parámetros de solicitud "de" (fecha) y "a" opcionales, como
http://localhost:9000/birthdays?from=20120131&to=20120229
(fechas aquí interpretadas como aaaaMMdd)
Mi pregunta es cómo manejar el enlace y la interpretación de param de solicitud en Play 2.0 con Scala, especialmente dado que estos dos parámetros deben ser opcionales.
¿Deberían estos parámetros ser expresados de alguna manera en la especificación de "rutas"? Alternativamente, ¿debería el método respondedor del controlador separar los params del objeto de solicitud de alguna manera? Hay otra manera de hacer esto?
Aquí está el ejemplo de Julien reescrito en java, usando F.Option: (funciona a partir del juego 2.1)
import play.libs.F.Option;
public static Result birthdays(Option<String> from, Option<String> to) {
// …
}
Ruta:
GET /birthday controllers.Application.birthday(from: play.libs.F.Option[String], to: play.libs.F.Option[String])
También puede seleccionar parámetros de consulta arbitrarios como cadenas (debe realizar la conversión de tipo usted mismo):
public static Result birthdays(Option<String> from, Option<String> to) {
String blarg = request().getQueryString("blarg"); // null if not in URL
// …
}
Mi forma de hacer esto implica usar un QueryStringBindable
personalizado. De esta manera expreso los parámetros en las rutas como:
GET /birthdays/ controllers.Birthdays.getBirthdays(period: util.Period)
El código para Period se ve así.
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
es solo un método de applyDateFilter
uso en mis controladores si deseo aplicar el filtro de fecha a la consulta. Obviamente, puede usar otros valores predeterminados de fecha aquí, o usar algún otro valor por defecto que no sea nulo para la fecha de inicio y finalización en el método de bind
.
Para los parámetros de consulta opcionales, puede hacerlo de esta manera
En el archivo de rutas, declare la API
GET /birthdays controllers.Application.method(from: Long, to: Long)
También puede dar un valor predeterminado, en caso de que la API no contenga estos parámetros de consulta, automáticamente asignará los valores predeterminados a estos parámetros.
GET /birthdays controllers.Application.method(from: Long ?= 0, to: Long ?= 10)
En el método escrito dentro de la aplicación del controlador, estos parámetros tendrán un valor null
si no hay valores predeterminados asignados a otros valores predeterminados.
Una forma quizás menos limpia de hacer esto para los usuarios de Java es establecer los valores predeterminados:
GET /users controllers.Application.users(max:java.lang.Integer ?= 50, page:java.lang.Integer ?= 0)
Y en el controlador
public static Result users(Integer max, Integer page) {...}
Un problema más, tendrá que repetir los valores predeterminados cada vez que enlace a su página en la plantilla
@routes.Application.users(max = 50, page = 0)
Codifique sus parámetros opcionales como Option[String]
(u Option[java.util.Date]
, pero tendrá que implementar su propio QueryStringBindable[Date]
):
def birthdays(from: Option[String], to: Option[String]) = Action {
// …
}
Y declara la siguiente ruta:
GET /birthday controllers.Application.birthday(from: Option[String], to: Option[String])