参考URL
概要
コントローラ内のアクションメソッドの実行前(後)に必ずなにか処理を実行したい場合、 Interceptor を利用します。
コントローラに処理が移る前(後)に(つまりアクセスのたびに)必ずなにか処理を実行したい場合 Filter を利用します。
InterceptorとFilterはとても便利な機能で、公式ドキュメントもシンプルでわかりやすいです。(GORMと違って。。。)
むしろ公式だけ見たほうが説明が簡潔で分かりやすいです。
ただ、処理の前後に必ず実行したいものが有る場合どうすればいいの?という疑問を持ったときに公式ドキュメントのどこを見ればいいのかわからなかったので、リファレンス的にこの記事を書きました。
必ず実行する処理の典型例のログイン機能はSpringSecurityCoreなど便利なプラグインに任せたほうがいいので、じゃあSpringSecurityCoreを使っている場合の動作はどうなるの?ということも一緒にまとめました。
SpringSecurityCore自体の使い方はこちら
Interceptor
Interceptorの公式ドキュメントが非常にわかりやすいのでそちらを見れば基本的に全てわかります。
Interceptorを使えば、アクションメソッド実行前後に必ず実行する処理を簡潔に記述できます。
*上記ドキュメント内に ".&"という記述があります。これはGrailsではなくてGroovyの機能で、インスタンスメソッドをクロージャに変換させるものです。詳細はこちら
なお、SpringSecurityCoreプラグインを利用している場合、コントローラが以下のような場合を仮定します。
@Secured(['IS_AUTHENTICATED_FULLY', 'ROLE_ADMIN'])
class HelloController {
def beforeInterceptor = {println "beforeInterceptor"}
def index() {
...
}
@Secured(['IS_AUTHENTICATED_ANONYMOUSLY'])
def index2(){
...
}
}
簡単に説明すると、このコントローラにアクセスすると、原則ログインしている必要があるけど、index2へのアクセスの場合はログインしていなくてもOK、となります。
indexアクションへのアクセスの場合
ログインしていない状態でアクセスすると、 SpringSecurityCoreによって 、beforeInterceptorが実行される前にログイン画面にリダイレクトされます。そのため コントローラ内のIterceptorとアクションメソッドは実行されません。
ログインしていれば、beforeInterceptorが実行され、その後インデックスアクションが実行されます。
index2アクションへのアクセスの場合
ログインしていなくてもOKなので、必ずbeforeInterceptorが実行され、index2アクションが実行荒れます。
Filter
Filterの公式ドキュメンが非常にわかりやすいのでそちらを見れば基本的にすべてわかります。
Filterを使えば、各コントローラ実行前後に必ず実行する処理を簡潔に記述できます。
今回以下のようなFilterを記述しました。
package filters.test
class TestFilters {
def filters = {
all(controller:'*', action:'*') {
before = {
println "Filter"
}
after = { Map model ->
}
afterView = { Exception e ->
}
}
}
}
Filterの場合、Interceptorと違ってSpringSecurityCoreの影響を受けません。
上記の場合、どのコントローラにアクセスしようとしても最初にかならずbeforeが実行されます。
その後、各コントローラに処理が移ります。
以下何点かメモ。
grails-app/confディレクトリ配下ににxxxFilters.groovyというFilterを作成するだけだけど、confの下に更にディレクトリを作ってその中にFilterを置いてもOK
その場合、Filterのパッケージ名は自分の所属するディレクトリ名にします。
例えば、grails-app/conf/myFilters/hoge/ExampleFilters.groovyを作成した場合、ExampleFilters.groovyのパッケージ宣言はpackage myFilters.hoge
となります。
Grailsアプリケーションのパッケージ名は関係ない点に注意。
404の場合はFilterは実行されません。
まとめ
SpringSecuritCoreを利用している場合のFilter、Interceptorの実行順序は以下のようになります。
1. Filter(before)が実行される。
2. 各コントローラに処理が移る。
3. 各コントローラのアクションメソッドを実行する際にSpringSecurityCoreがログイン状態/権限等をチェックする。
4. SpringSecurtyCoreが必要だと判断すれば、SpringSecurityCoreが用意するログイン画面にリダイレクトされ、 コントローラ内のIterceptorとアクションメソッドは実行されない。
5. 1から4が繰り返される。
6. SpringSecurityCoreのチェックをパスすればInterceptor(beforeInterceptor)が実行される。
7. アクションメソッドが実行される。
8. Interceptor(afterInterceptor)が実行される。
9. Filter(after)が実行される。
10. Viewが表示される。
11. Filter(afterView)が実行される。