Play 2 - Установить заголовок для всех ответов?
Я знаю из Настройка заголовков HTTP в Play 2.0 (scala)?, чтобы вы могли настраивать заголовки ответов в каждом конкретном случае, например, Ok("hello").withHeaders(PRAGMA -> "no-cache")
.
Что делать, если вы хотите установить этот заголовок или несколько разных заголовков на ответы всех ваших действий? Вы не хотели бы повторять withHeaders
всюду. И поскольку это больше похоже на конфигурацию на уровне приложения, вам может не потребоваться, чтобы авторы действий использовали другой синтаксис для получения заголовков (например, OkWithHeaders(...)
)
Теперь у меня есть базовый класс контроллера, который выглядит как
class ContextController extends Controller {
...
def Ok(h: Html) = Results.Ok(h).withHeaders(PRAGMA -> "no-cache")
}
но это не совсем правильно. Похоже, что должно быть больше стиля AOP для определения заголовков по умолчанию и добавления их в каждый ответ.
Ответы
Ответ 1
В своем 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, что имеет наибольшее значение для инструкции no-cache.
Ответ 2
Тема довольно старая, но с 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"
))
}
}
Ответ 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!")
}
Ответ 4
Есть слишком способы. Вы можете использовать action-composition. Затем вы должны объявить на каждом контроллере, что вы хотите установить здесь заголовок. Другой вариант - использовать GlobalSettings.
Аналогичные решения для java тоже.