Lv.7 カスタムActionはサーブレットフィルターみたいなもの [play framework2.0] [java]

アクションはメソッドだけど、クラスとして定義されたものをメソッドとして使っている、
というのが実際のところ。

※第一級関数(first class function)
関数をオブジェクトとして扱って、ほかの関数の引数として使ったり、データ構造に含めたりできる関数のことをこう呼ぶらしい。

第一級関数※がJavaでは定義できないのが理由らしいです。
play.mvc.ActionがルートActionとしてデフォルトで用意してあるので、こちらを継承して
独自Actionを定義することも可能です。
独自で用意するアクションは、意味合い的にはサーブレットフィルターが近い
かもしれないです。

(play.mvc.Actionのコード)

[java toolbar=”false”]
public abstract class Action<T> extends Results {
public T configuration;
public Action<?> delegate;
public abstract Result call(Context ctx)
throws Throwable;
public static abstract class Simple
extends Action<Void> {}
}[/java]

目次

Actionを作る!使う!

※ちなみにverboseとは、「くどい」「冗長な」という意味らしい。

まずはアクションを作る。

[java toolbar=”false”]
public class VerboseAction extends Action.Simple {
public Result call(Http.Context ctx) throws Throwable {
Logger.info(“Calling action for ” + ctx);
//こうすることで処理を引き継げる(委譲)
return delegate.call(ctx);
}
}[/java]
※ミックスして使える、と公式ドキュメントに書いてあるけど、コンパイル通らない。なにか前提条件があるのだろうか。

[java light=”true”]
@With(Authenticated.class, Cached.class)
public static Result index() {
return ok(“It works!”);
}[/java]

使い方は、こう。

[java toolbar=”false”]
@With(VerboseAction.class)
public static Result index() {
return ok(“It works!”);
}[/java]

カスタムActionアノテーション

まずアノテーションの定義をする。

[java toolbar=”false”]
@With(VerboseAction.class)
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Verbose {
boolean value() default true;
}[/java]
※Classに直接アノテーションを書くこともできる。

[java light=”true”]
@Authenticated
public Admin extends Controller {

}[/java]

次にControllerクラスでActionメソッドにアノテーションを適用する。※

[java toolbar=”false”]
@Verbose(false)
public static Result index() {
return ok(“It works!”);
}
[/java]

そしてVerboseインターフェースをジェネリクスに指定したActionを継承した
Verboseアクションクラスを作る。

[java toolbar=”false”]
public class VerboseAction extends Action<Verbose> {
public Result call(Http.Context ctx) throws Throwable{
if(configuration.value()) {
// @Verbose(true)だとこっち。
Logger.info(“action kita! ” + ctx);
}else{
// @Verbose(false)だとこっち。
Logger.info(“no action “);
}
return delegate.call(ctx);
}
}[/java]

これで動きました。

アセスメント

  • カスタムActionの作り方が分かる
  • カスタムActionアノテーションの使い方が分かる

参照した公式ドキュメントは、Action compositionです。