Play2でHttpSessionを使う

play2-war-pluginを使うとPlay2アプリケーションをwarにしてサーブレットコンテナ上で利用することができますが、さらにサーブレットのHttpSessionを利用できるようにするためのplay2-httpsessionというライブラリを作ってみました。

まずはBuild.scalaに以下の依存関係を追加します。

resolvers += "amateras-repo" at "http://amateras.sourceforge.jp/mvn/"

libraryDependencies += "jp.sf.amateras.play2.httpsession" %% "play2-httpsession" % "0.0.2"

コントローラでjp.sf.amateras.play2.httpsession.HttpSessionSupport._をインポートします。以下のようにSessionの代わりにHttpSession、withSessionの代わりにwithHttpSessionを使用することでPlay2のセッションと同じ感覚でHttpSessionを利用できます。

import jp.sf.amateras.play2.httpsession.HttpSessionSupport._

def index = Action { implicit request =>
  // retrieve the object from HttpSession
  val count = (HttpSession[String]("counter") match {
    case None    => 0
    case Some(i) => i.toInt
  }) + 1

  Ok("count=%d".format(count)).withHttpSession {
    // store objects into HttpSession
    "counter" -> count.toString
  }
}

アプリケーションの開発中はplay runで動作確認を行うと思いますが、この場合でも擬似的にセッションを利用できるようになっています。ただし、開発モードで動作を確認するための簡易的な実装であるため、現状ではクライアントやブラウザを問わず同一のセッションと見なされるという点に注意してください。
なお、play2-war-pluginをServlet 2.5モードで動作させる場合はplay2-war-pluginが生成したwar/WEB-INF/web.xmlに以下の記述を追加する必要があります。

<listener>
  <listener-class>jp.sf.amateras.play2.httpsession.HttpSessionListener</listener-class>
</listener>

<filter>
  <filter-name>encoding</filter-name>
  <filter-class>jp.sf.amateras.play2.httpsession.CharacterEncodingFilter</filter-class>
  <init-param>
    <param-name>requestEncoding</param-name>
    <param-value>UTF-8</param-value>
  </init-param>
</filter>

<filter>
  <filter-name>session</filter-name>
  <filter-class>jp.sf.amateras.play2.httpsession.HttpSessionFilter</filter-class>
</filter>

<filter-mapping>
  <filter-name>encoding</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
  <filter-name>session</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

HttpSessionはアプリケーションにステートを持ち込んでしまうため、Play2の設計思想には反するものですが、既存のサーブレットベースのWebアプリケーションを移植する場合には使えないと不便なことも多いと思います。そのような場合にはplay2-war-pluginとあわせて利用することを想定しています。