1

私は Play Framework 2.0.3 を使用しており、動的に決定されるアプリ内の URL に特定のリクエスト (つまり、301/302なし) を内部的に再ルーティングするフィルターを追加したいと考えています。つまり、転送する必要があるエンドポイントはリクエストに依存するため、コンパイル時にそれがどのコントローラー/アクションになるかがわからず、それらを直接呼び出すことはできません。

たとえば、 のリクエストを受け取ったGET /foo?redirectTo=/bar場合、それが実際に であるかのように Play 内部でルーティング/処理するにはどうすればよいPOST /barでしょうか?

この要点はこれまでのところ私の最善の推測ですが、いくつかの制限があります: https://gist.github.com/brikis98/5582159

4

3 に答える 3

0

さて、ここにうまくいくように見える解決策があります:

object RedirectFilter extends Filter {

  def apply(next: RequestHeader => Result)(request: RequestHeader): Result = {

    getRedirectParams(request).flatMap { case (newRequest, body) =>
      route(newRequest).map { iteratee =>
        AsyncResult(Enumerator(body).run(iteratee))
      }
    } getOrElse {
      next(request)
    }
  }

  private def getRedirectParams(request: RequestHeader): Option[(RequestHeader, Array[Byte])] = {
    if (someCondition) {
      Some(toPostRequest(request), "Some new body data".getBytes("UTF-8"))      
    } else {
      None
    }
  }

  private def toPostRequest(originalRequest: RequestHeader): RequestHeader = {
    originalRequest.copy(
      uri = "/some/new/uri",
      path = "/some/new/uri",
      method = "POST"
    )
  }

  private def route(request: RequestHeader): Option[Iteratee[Array[Byte], Result]] = {
    Play.global.onRouteRequest(request).collect {
      case action: EssentialAction => Play.global.doFilter(action)(request)
    }
  }

}

他の有用なコメントについては、この要点を確認してください。

于 2013-05-17T18:51:52.943 に答える