2010年3月16日火曜日

[Lift] 無駄に新規セッションを生成させずに条件によってリダイレクトする方法

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
リクエストヘッダの条件によってリダイレクトを行うには、snippet内でS.redirectToを使ってリダイレクトするのが一番簡単な方法ですが、Liftでsnippetを使うと必ずセッションを生成してくれます。検索エンジンのクローラbotとかからアクセスがある度に無駄にセッションが生成されてしまってサーバリソースを無駄に使っていたので、こんな感じで不要な場合はセッションが生成される前にリダイレクトさせてみました。
// Boot.scala の def boot内
LiftRules.statelessDispatchTable.prepend {  // *1
  case MyReq("venue" :: vid :: _, r) if r.header("User-Agent") == Full("何か") => // *2
    () => Full(RedirectResponse("http://foursquare.com/venue/" + vid))
}

object MyReq {  // *3
  def unapply(in: Req): Option[(List[String], HTTPRequest)] = 
    Some((in.path.partPath, in.request))
}
  1. LiftRules.statelessDispatchTableにPartialFunction[Req, () => Box[LiftResponse]]を追加しておくと、セッション生成前に条件にマッチした場合は戻り値のLiftResponseをクライアントに返してくれます。
  2. 通常は、Req(パス, 拡張子, リクエストタイプ)でパターンマッチさせますが、ここではリクエストの内容によって判断したいため、*3で独自の抽出子(extractor)を定義し、抽出したHTTPRequestの中身(上記例ではリクエストヘッダ)をパターンガード条件として使用しています。
  3. unapplyメソッドを持つobjectが抽出子です。参照:コップ本第24章(p.440)
抽出子とパターンガードを使うとパターンマッチが益々便利です。

0 件のコメント:

コメントを投稿