scala – 如何在PlayFramework中从截取的请求将变量传递给Action
我通过覆盖GlobalSettings的onRouteRequest方法来拦截对我的播放应用程序的所有请求.现在,我需要从这里向调度的动作发送一些数据,这样我就不会在所有动作中执行所有这些计算.如何设置我传递给超级onRouteRequest方法的请求(play.api.mvc.RequestHeader)对象的属性?
解决方法
根据您的需要,我不会使用onRouteRequest工作(至少优雅).
但是,让我们尝试使用专用结构来拦截. 以下是拦截请求,计算一些通用内容并将其传递给Action的方法 首先,这里是一个Interceptor对象,它有一个方法拦截和一个方便的方法用户名: object Interceptor { def intercept[A,B](f: RequestHeader => Option[B],e: RequestHeader => Result)(action: B => Action[A]): Action[(Action[A],A)] = { val bodyParser = BodyParser { request => f(request) map { b => val innerAction = action(b) innerAction.parser(request).mapDone { body => body.right.map(innerBody => (innerAction,innerBody)) } } getOrElse { Done(Left(e(request)),Input.Empty) } } Action(bodyParser) { request => val (innerAction,innerBody) = request.body innerAction(request.map(_ => innerBody)) } } def username[A](check: RequestHeader => Option[String]): ((String) => Action[A]) => Action[(Action[A],A)] = intercept(check,r => Results.Unauthorized("not logged in")) } 如您所见,worker函数拦截使您有机会根据请求内容计算某些内容. B类型的哪个计算结果可能会失败(选项),在这种情况下,处理程序会告诉您该怎么做. 定义了要计算的内容之后,您可以使用一个带有B并给出Action [A]的函数来定义您的动作. username方法只是一个简单的预定义拦截器,它可以让我们定义如何检索登录的用户名,只是为了说明. 现在,我们可以在Controller中使用它们 //index is defined for both GET and POST in routes,but fails on POST // thanks to the interceptor that checks at first the used method // the case mustn't be handled in the Action definition def index = Interceptor.intercept( /*check the method*/ request => if (request.method == "GET") Some(request.method) else None,/*not a GET => bad request*/ request => BadRequest(request.method + " not allowed") ) { /*the computation result*/method => Action { Ok("The method : " + method) } } //this controller retrieve the username in the session and renders it in a OK response def secured = Interceptor.username(r => r.session.get("username")) { username => Action { Ok("You're logged in as " + username) } } //this enables you to logged in => store in session def login(u:String) = Action { request => { Ok("Logged in as " + u) withSession(("username" -> u)) } } 现在,如果你有一个通用计算,你可以创建你的预配置拦截器(这里我使用一个案例类,但只是定义一个部分应用拦截器的函数就足够了) case class Intercept[B] (f: RequestHeader => Option[B],e: RequestHeader => Result) { def apply[A](action: B => Action[A]) = Interceptor.intercept[A,B](f,e)(action) } val getInterceptor = Intercept[String]( request => if (request.method == "GET") Some(request.method) else None,request => BadRequest(request.method + " not allowed") ) def index2 = getInterceptor { method => Action { Ok("Da method : " + method) } } 与评论相关的编辑: 根据你的评论,这里是你如何使用拦截器(注意我已经模拟了主机检索和检查) 使用hosted和anotherHosted,您将能够测试此工作流程: > / hosted / false?host = myhost => 404,因为最初myhost没有被缓存,我向被检查的模型提供了false 这是代码 def getHost(request:RequestHeader) = request.queryString.get("host").get.head def checkHost(host:String,b: Boolean) = b val checkHosted = (b: Boolean) => Intercept[String]( request => { val host = getHost(request) Cache.getAs[String](host) match { case x@Some(_) => x case None => if (checkHost(host,b)) { Cache.set(host,host) Some(host) } else None } },request => NotFound(getHost(request) + "not hosted") ) def hosted(b:String) = checkHosted(b.toBoolean) { host => Action { Ok("this host is ok : " + host) } } def anotherHosted(b:String) = checkHosted(b.toBoolean) { host => Action { Ok("this host is ok : " + host) } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |