Play framework 2.0 のためのブログです。
3月
2
Comments

ActionのFilter処理を実行するためのTips。

ドキュメントだと、ActionsComposition のこと↓
https://www.playframework.com/documentation/2.3.x/ScalaActionsComposition

今回、Filterの処理内容をTraitとして実装する方法としました。
また、DBアクセスにSlickを使用し、FilterからもDBアクセスできるような実装となっております。

AuthTrait (Filter実装部)

  1. package controllers.components.actions  
  2.   
  3. import models.Users  
  4. import play.api.db.slick._  
  5. import play.api.mvc.{Result, Request, Action}  
  6. import play.api.Play.current  
  7.   
  8. import scala.concurrent.Future  
  9.   
  10. /** 
  11.  * Created by yusuke on 2015/01/23. 
  12.  */  
  13. trait AuthTrait {  
  14.   
  15.   case class Auth[A](action: Action[A]) extends Action[A] {  
  16.     def apply(request: Request[A]): Future[Result] = {  
  17.       DB.withSession {implicit session =>  
  18.   
  19.         // DB.withSession 内 であれば、Slick経由でDBアクセス可能  
  20.         // ここでFilter処理を記載する  
  21.         // println(Users.findById(1));  
  22.   
  23.       }  
  24.   
  25.       action(request)  
  26.     }  
  27.     lazy val parser = action.parser  
  28.   }  
  29. }  

Application (Controller)
  1. package controllers  
  2.   
  3. import controllers.components.actions.AuthTrait  
  4. import models.Users  
  5. import play.api.mvc._  
  6. import play.api.db.slick._  
  7. import play.api.Play.current  
  8.   
  9. object Application extends Controller with AuthTrait{  
  10.   
  11.   // 通常アクション  
  12.   def index = Action{  
  13.     Ok(views.html.index("Your new application is ready."))  
  14.   }  
  15.   
  16.   // Authフィルターを使用 (中身はAuthTraitに実装)  
  17.   def test = Auth {  
  18.     // アクションでDBアクセスする場合はDBAction, しない場合はActionでもOK  
  19.     DBAction { implicit rc =>  
  20.       Ok(Users.findById(1).toString)  
  21.     }  
  22.   }  
  23.   
  24. }  

複数のFilterをかけたい場合は、同様の形でTraitを定義し、ActionにWrapする形で重ねがけすればOK。重ねる順番で、外側から順番にFilter処理が走ります。
以下の例だと、Filter1実行 → Filter2実行 → DBAction実行
  1. def hoge = Filter1{  
  2.   Filter2{  
  3.     DBAction{  
  4.     }  
  5.   }  
  6. }  
以上です。


 --------------以下追記---------------
ちなみに、POSTデータを取得するには、以下のようにする

① クラスを定義してバインドするパターン

  1. trait AuthTrait {  
  2.   
  3.   // フォームに対応するエンティティを定義  
  4.   case class AuthEntity(uid: String, name: String)  
  5.   val auth_form = Form(mapping("uid" -> text, "name" -> text)(AuthEntity.apply)(AuthEntity.unapply))  
  6.   
  7.   case class Auth[A](action: Action[A]) extends Action[A] {  
  8.     def apply(request: Request[A]): Future[Result] = {  
  9.       DB.withSession {implicit session =>  
  10.   
  11.         // リクエストをフォームにバインドして、値を取り出す  
  12.         println(auth_form.bindFromRequest()(request).get.name)  
  13.         
  14.       }  
  15.       action(request)  
  16.     }  
  17.     lazy val parser = action.parser  
  18.   }  
  19. }  
② バインドせずに、取り出すパターン
  1. val postData: Map[String, Seq[String]] = request.body.asInstanceOf[AnyContentAsFormUrlEncoded].data  
  2. println(postData.get("uid").get(0))  






Categories: , ,

Leave a Reply