1

すべてのリクエストで YMD uri 日付パラメーターの存在を確認する必要があります。存在する場合は、アプリケーションのさまざまな部分で後でアクセスできるように、暗黙のリクエストが利用可能になっている場所にそれを保存します。

リクエストの傍受は当然の選択のようです: https://github.com/playframework/Play20/wiki/ScalaInterceptors

ただし、リクエストに追加する方法がわかりません(実際にRequestHeaderは利用可能なものです)。読み取り専用/不変であると仮定します。

Action Compositionを介して Request にデータを追加できます。ただし、このアプローチは構成されたアクションに限定されており、すべてのアクションではありません (なぜ、上記のグローバルなインターセプター前のアプローチが何らかの形で機能することを望むのですか)。たとえば、Authentiucated アクション ラッパーを使用すると、ログインしているユーザーの ID をリクエストに格納できます。

trait Secured { 
  private case class Success[A](uid: Int, r: Request[A]) extends WrappedRequest(r)

  def Authenticated[A](p: BodyParser[A])
    (f: Success[A] => Result)(implicit group: RoleGroup) = {

    def apply(maybeUser: Option[String])(implicit r: Request[A]) = {
      maybeUser map {id =>
        Cache.orElse(group.to_s+"-"+id, 3600){
          repo.user.get(id.int, group) map(_.active) getOrElse false
      } fold ( onFail, f(Success(id.int, r)) )
    }
  }

可能性のある uri 日付パラメーターについても同じことを行いたいのですが、それをすべてのアクションに適用するか、グローバル インターセプターを介して Play ルート メカニズムがトリガーされる前に適用する必要があります。

アイデアは大歓迎です、ありがとう

4

1 に答える 1

0

リクエストへの任意のデータの挿入をシミュレートするために、WrappedRequestを拡張できます。

case class Outcome[A](
  r: Request[A], 
  uid: Int, 
  startDate: String,
  endDate: String,
  uriDate: JodaTime) extends WrappedRequest(r)

次に、カスタムリクエストラッパーのインスタンスを返すアクションプロバイダー特性を作成します。たとえば、基本タスクアクションは次のようになります。

trait TaskRequest 
  extends DateParser {

  def Task[A](p: BodyParser[A])(f: Outcome[A] => Result) = {
    Action(p) { implicit r =>
      f( toOutcome[A](r, r.session.get("userID").map(_.toInt) getOrElse 0) )
    }
  }
  def Task(f: Outcome[AnyContent] => Result): Action[AnyContent] = {
    import play.api.mvc.BodyParsers._
    Task(parse.anyContent)(f)
  }

  protected def toOutcome[A](r: Request[A], uid: Int) = {
    val(start,uriDate) = (startDate(r), toDate(r.uri))
    val end = seasonEnd(start)
    Outcome(r, uid, start.toString("yyyyMMdd"), end.toString("yyyyMMdd"), uriDate)
  }

  val ymdMatcher = "\\d{8}".r  
  protected def startDate(uri: String) = {
    ymdMatcher.findFirstIn(uri). // set season start based on ymd URI param if exist 
    map(_.startDate) getOrElse seasonStart(new JodaTime)
  }

  protected def toDate(uri: String) =
    ymdMatcher.findFirstIn(r.uri).map(_.to_date) getOrElse new JodaTime
}

次に、タスクから認証済みアクションを導出します。

trait Secured
  extends TaskRequest { 

  def Authenticated[A](p: BodyParser[A])
    (f: Outcome[A] => Result)(implicit group: RoleGroup) = {

    def apply(maybeUser: Option[String])(implicit r: Request[A]) = {
      maybeUser map {id =>
        Cache.orElse(group.to_s+"-"+id, 3600){
          repo.user.get(id.int, group) map(_.active) getOrElse false
      } fold ( onFail, f( toOutcome(r, id.int)) )
    }
  }

次に、コントローラーで使用します。

def index = Authenticated { implicit request=>
  // voila, current season start date since no uri date param exist
  request.startDate
}

確かに、アクションごとに日付操作関数を呼び出すことはできますが、それはアクションスコープにのみ適用されます。テンプレートレイヤーのstartDateにアクセスするにはどうすればよいですか?できませんでしたが、カスタムリクエストラッパーを使用すると、必要なものを挿入して、どこからでも簡単にデータを参照できます。したがって、プレイのリクエストをスコープに入れる代わりに、次のようにします。

@(model: Foo, title: String)(implicit request: play.api.mvc.Request[_])

カスタムリクエストラッパーを参照します。

@(model: Foo, title: String)(implicit request: controllers.Outcome[_])

仕事は非常にうまくいきますか、グローバルインターセプトはまだ使用法を見つけていません(おそらくいくつかのレガシーURIを再ルーティングしますが、WrappedRequestアプローチほど強力ではありません)

于 2012-11-02T08:26:06.123 に答える