Scala=のような、機能しているPlay 2.0フレームワークベースのアプリケーションが既にあるとしましょう。
http:// localhost:9000/birthdays
すべての既知の誕生日のリストで応答します
オプションの「from」(日付)および「to」リクエストパラメータなどの結果を制限する機能を追加することで、これを強化したい
http:// localhost:9000/birthdays?from = 20120131&to = 20120229
(ここでの日付はyyyyMMddと解釈されます)
私の質問は、Scalaを使用したPlay 2.0でリクエストパラメーターのバインドと解釈を処理する方法です。特に、これらのパラメーターの両方をオプションにする必要がある場合です。
これらのパラメータは、「ルート」仕様で何らかの形で表現する必要がありますか?あるいは、応答するControllerメソッドは、何らかの方法でリクエストオブジェクトからパラメーターを選択する必要がありますか?これを行う別の方法はありますか?
オプションのパラメーターをOption[String]
(またはOption[Java.util.Date]
としてエンコードしますが、独自のQueryStringBindable[Date]
を実装する必要があります):
def birthdays(from: Option[String], to: Option[String]) = Action {
// …
}
そして、次のルートを宣言します。
GET /birthday controllers.Application.birthday(from: Option[String], to: Option[String])
Javaユーザーに対してこれを行うよりクリーンでない方法は、デフォルトを設定しています:
GET /users controllers.Application.users(max:Java.lang.Integer ?= 50, page:Java.lang.Integer ?= 0)
そしてコントローラーで
public static Result users(Integer max, Integer page) {...}
もう1つの問題は、テンプレート内のページにリンクするたびにデフォルトを繰り返す必要があることです。
@routes.Application.users(max = 50, page = 0)
ジュリアンの答えに加えて。 routesファイルに含めたくない場合。
RequestHeaderを使用して、コントローラーメソッドでこの属性を取得できます。
String from = request().getQueryString("from");
String to = request().getQueryString("to");
これにより、目的のリクエストパラメータが得られ、さらにroutesファイルがクリーンになります。
これは、F.Optionを使用してJavaで書き直されたJulienの例です:(play 2.1以降で動作します)
import play.libs.F.Option;
public static Result birthdays(Option<String> from, Option<String> to) {
// …
}
ルート:
GET /birthday controllers.Application.birthday(from: play.libs.F.Option[String], to: play.libs.F.Option[String])
任意のクエリパラメータを文字列として選択することもできます(自分で型変換を行う必要があります)。
public static Result birthdays(Option<String> from, Option<String> to) {
String blarg = request().getQueryString("blarg"); // null if not in URL
// …
}
オプションのクエリパラメータについては、この方法で行うことができます
Routesファイルで、APIを宣言します
GET /birthdays controllers.Application.method(from: Long, to: Long)
APIにこれらのクエリパラメータが含まれていない場合、デフォルト値をこれらのパラメータに自動的に割り当てます。
GET /birthdays controllers.Application.method(from: Long ?= 0, to: Long ?= 10)
コントローラーアプリケーション内に記述されたメソッドでは、これらのパラメーターの値は、デフォルト値が割り当てられていない場合はデフォルト値が割り当てられていない場合はnull
になります。
これを行う私の方法には、カスタムQueryStringBindable
の使用が含まれます。この方法で、ルートのパラメーターを次のように表現します。
GET /birthdays/ controllers.Birthdays.getBirthdays(period: util.Period)
Periodのコードは次のようになります。
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
は、クエリに日付フィルタリングを適用する場合にコントローラーで使用する便利な方法です。明らかに、ここで他の日付のデフォルトを使用するか、bind
メソッドの開始日と終了日にnull以外のデフォルトを使用できます。