ActionのFilter処理を実行するためのTips。
ドキュメントだと、ActionsComposition のこと↓
https://www.playframework.com/documentation/2.3.x/ScalaActionsComposition
今回、Filterの処理内容をTraitとして実装する方法としました。
また、DBアクセスにSlickを使用し、FilterからもDBアクセスできるような実装となっております。
AuthTrait (Filter実装部)
package controllers.components.actions
import models.Users
import play.api.db.slick._
import play.api.mvc.{Result, Request, Action}
import play.api.Play.current
import scala.concurrent.Future
/**
* Created by yusuke on 2015/01/23.
*/
trait AuthTrait {
case class Auth[A](action: Action[A]) extends Action[A] {
def apply(request: Request[A]): Future[Result] = {
DB.withSession {implicit session =>
// DB.withSession 内 であれば、Slick経由でDBアクセス可能
// ここでFilter処理を記載する
// println(Users.findById(1));
}
action(request)
}
lazy val parser = action.parser
}
}
Application (Controller)
package controllers
import controllers.components.actions.AuthTrait
import models.Users
import play.api.mvc._
import play.api.db.slick._
import play.api.Play.current
object Application extends Controller with AuthTrait{
// 通常アクション
def index = Action{
Ok(views.html.index("Your new application is ready."))
}
// Authフィルターを使用 (中身はAuthTraitに実装)
def test = Auth {
// アクションでDBアクセスする場合はDBAction, しない場合はActionでもOK
DBAction { implicit rc =>
Ok(Users.findById(1).toString)
}
}
}
複数のFilterをかけたい場合は、同様の形でTraitを定義し、ActionにWrapする形で重ねがけすればOK。重ねる順番で、外側から順番にFilter処理が走ります。
以下の例だと、Filter1実行 → Filter2実行 → DBAction実行
def hoge = Filter1{
Filter2{
DBAction{
}
}
}
以上です。--------------以下追記---------------
ちなみに、POSTデータを取得するには、以下のようにする
① クラスを定義してバインドするパターン
trait AuthTrait {
// フォームに対応するエンティティを定義
case class AuthEntity(uid: String, name: String)
val auth_form = Form(mapping("uid" -> text, "name" -> text)(AuthEntity.apply)(AuthEntity.unapply))
case class Auth[A](action: Action[A]) extends Action[A] {
def apply(request: Request[A]): Future[Result] = {
DB.withSession {implicit session =>
// リクエストをフォームにバインドして、値を取り出す
println(auth_form.bindFromRequest()(request).get.name)
}
action(request)
}
lazy val parser = action.parser
}
}
② バインドせずに、取り出すパターンval postData: Map[String, Seq[String]] = request.body.asInstanceOf[AnyContentAsFormUrlEncoded].data
println(postData.get("uid").get(0))