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))