[play1-controller]インタセプタ機能について

  playframework1

概要

@After, @Before, @Finally, @Catch といったアノテーションを使うと、アクション処理、テンプレート処理の間に、アノテーションを付けたメソッドが実行される。
ログイン状態のチェックなど複数のアクションに対して適用したいときに便利。

適用

自クラス、@With指定クラス、継承元クラスに記述したアノテーションが有効。

インタセプタによって機能拡張するにあたって、継承元クラスだと1つしか選択できず不便なことから@Withによる指定ができるようになっている。

@With( { Extention1.class, Extention2.class } )
public class Application extends Controller {
    ...

インタセプタアノテーションを付与するメソッドは、publicである必要は無い。

@Before

アクション実行前に実行したいメソッドに付与する。
onlyで対象となるアクション名を複数指定することができる。
unlessで対象外とするアクション名を複数指定することができる。

@After

アクション実行後に実行したいメソッドに付与する。
@Beforeと同様にonly, unlessが指定できる。

@Finally

テンプレート処理が行われた後に実行したいメソッドに付与する。
@Beforeと同様にonly, unlessが指定できる。
この時点では flash変数やsession変数などは辿れくなっており参照しても正しい値を返さなくなっている。例えば@FinallyでログにセッションIDを出力したいときは素直に書けないので注意。

@Catch

アクション処理で例外が発生したときに実行したいメソッドに付与する。
捕捉したい例外クラスを複数指定できる。

@Catch( { IllegalArgumentException.class, PlayException.class } )

実行順

@Before → action → @After → template → @Finally

@Catch はactionメソッドで例外が発生すると実行される。
各アノテーションには priorityというint値を指定でき、これが小さいほど先に実行される。指定しないとゼロが指定されたものとして動作する。

ゼロが最高レベル、とコメントには書いてあるがint型なのでマイナス値を使えばさらに優先されるだろう。

実装を見ると、自クラス→@With指定クラス→継承元、という走査を再帰的に行っているようなので、同じpriorityの場合はそれに沿った挙動になるはずだが今後も変わらない保証はない。
基本はpriorityによる指定をすべき。

LEAVE A COMMENT