§リクエストインターセプター
§フィルタの利用
フィルターとは、アプリケーションへ送られてきたリクエストをインターセプト(傍受)したり、リクエストまたはレスポンスに変換処理を行うことを可能にするコンポーネントです。フィルターを使うと、アプリケーションを横断する関心事をうまく実装することができます。フィルターは Filter
トレイトを継承して実装され、 Global
へ追加されることで機能します。次の例では、全てのアクションの実行結果のログをとるアクセスログフィルターを実装しています。
import play.api.mvc._
object Global extends WithFilters(AccessLog)
object AccessLog extends Filter {
override def apply(next: RequestHeader => Result)(request: RequestHeader): Result = {
val result = next(request)
play.Logger.info(request + "\n\t => " + result)
result
}
}
Global
オブジェクトは WithFilters
クラスを継承しており、複数のフィルタを渡すとフィルタチェインをつくってくれます。
Note 現在、
WithFilters
はGlobalSettings
トレイトを継承しています
次の例は非常に有用なフィルタで、アクションの呼び出し前にアクセス認可チェックを行うというものです。
object Global extends WithFilters(AuthorizedFilter("editProfile", "buy", "sell")) with GlobalSettings {}
object AuthorizedFilter {
def apply(actionNames: String*) = new AuthorizedFilter(actionNames)
}
class AuthorizedFilter(actionNames: Seq[String]) extends Filter {
override def apply(next: RequestHeader => Result)(request: RequestHeader): Result = {
if(authorizationRequired(request)) {
/* do the auth stuff here */
println("auth required")
next(request)
}
else next(request)
}
private def authorizationRequired(request: RequestHeader) = {
val actionInvoked: String = request.tags.getOrElse(play.api.Routes.ROUTE_ACTION_METHOD, "")
actionNames.contains(actionInvoked)
}
}
Tip
RequestHeader.tags
には、アクションの呼び出しに利用されたルートに関する有益な情報が色々と含まれています
§onRouteRequest をオーバライドする
> **Tip** このフックは、リクエストをハイジャックして、開発者が任意のリクエストルーティング機構をプラグインする、という用途にも利用できます
早速、これを実践するとどうなるのか見てみましょう。
import play.api._
import play.api.mvc._
// Note: this is in the default package.
object Global extends GlobalSettings {
override def onRouteRequest(request: RequestHeader): Option[Handler] = {
println(“executed before every request:” + request.toString)
super.onRouteRequest(request)
}
}
```
ここで紹介した方法以外にも、 アクション合成 を使って特定のアクションメソッドだけをインターセプトする、というテクニックもあります。
次ページ: アプリケーションのテスト