我从Setting HTTP headers in Play 2.0 (scala)?了解到,您可以根据具体情况设置响应标头,例如Ok("hello").withHeaders(PRAGMA -> "no-cache")
。
如果您想在所有操作的响应中设置该标头或几个不同的标头,该怎么办?你不想在任何地方重复withHeaders
。由于这更像是应用程序范围的配置,您可能不希望Action编写者必须使用不同的语法来获取标题(例如OkWithHeaders(...)
)
我现在拥有的基本Controller类看起来像
class ContextController extends Controller {
...
def Ok(h: Html) = Results.Ok(h).withHeaders(PRAGMA -> "no-cache")
}
但这感觉不太对劲。感觉应该有更多的AOP风格的方法来定义默认标题并将它们添加到每个响应中。
答案 0 :(得分:14)
现在这个话题已经很老了,但是使用Play 2.1,它现在更简单了。
您的Global.scala
课程应如下所示:
import play.api._
import play.api.mvc._
import play.api.http.HeaderNames._
/**
* Global application settings.
*/
object Global extends GlobalSettings {
/**
* Global action composition.
*/
override def doFilter(action: EssentialAction): EssentialAction = EssentialAction { request =>
action.apply(request).map(_.withHeaders(
PRAGMA -> "no-cache"
))
}
}
答案 1 :(得分:8)
在Global.scala
中,将每个电话都包裹在一个动作中:
import play.api._
import play.api.mvc._
import play.api.Play.current
import play.api.http.HeaderNames._
object Global extends GlobalSettings {
def NoCache[A](action: Action[A]): Action[A] = Action(action.parser) { request =>
action(request) match {
case s: SimpleResult[_] => s.withHeaders(PRAGMA -> "no-cache")
case result => result
}
}
override def onRouteRequest(request: RequestHeader): Option[Handler] = {
if (Play.isDev) {
super.onRouteRequest(request).map {
case action: Action[_] => NoCache(action)
case other => other
}
} else {
super.onRouteRequest(request)
}
}
}
在这种情况下,我只在dev模式下调用动作,这对于无缓存指令最有意义。
答案 2 :(得分:3)
实现细粒度控制的最简单方法是使用包装操作。在你的情况下,它可能是这样的:
object HeaderWriter {
def apply(f: Request[AnyContent] => SimpleResult):Action[AnyContent] = {
Action { request =>
f(request).withHeaders(PRAGMA -> "no-cache")
}
}
}
以这种方式使用它:
def doAction = HeaderWriter { request =>
... do any stuff your want ...
Ok("Thats it!")
}
答案 3 :(得分:0)
还有很多方法。您可以使用action-composition。然后,您必须在每个Controller中声明要在此处设置标头。另一种选择是使用GlobalSettings。 java也有类似的解决方案。