1

我正在使用 Play Framework 2.0.3 并希望添加一个过滤器,该过滤器将在内部将某些请求(即没有301/302)重新路由到应用程序中动态确定的 URL 。也就是说,我需要转发到的端点取决于请求,所以我在编译时不知道它将是哪个控制器/动作,也不能直接调用它们。

例如,如果我收到对 的请求GET /foo?redirectTo=/bar,我如何才能让 Play 在内部路由/处理它,就好像它实际上是一个POST /bar

到目前为止,这个要点是我最好的猜测,但它有一些局限性:https ://gist.github.com/brikis98/5582159

4

3 回答 3

0

只需调用相应的控制器方法即可。

爪哇版:

public static Result foo() {
    return bar();
}

public static Result bar() {
    return ok();
}

我错过了什么吗?

于 2013-05-14T19:10:51.577 回答
0

因此,您需要将您的请求从 GET 请求转换为 POST。我不知道有任何自动的方法可以做到这一点,但它应该相当容易。

你能解释一下为什么你需要那个吗?

朱利安。

于 2013-05-14T20:11:02.583 回答
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 回答