在Play 2.6之前,我有一些自定义操作,例如我只需关心实现apply
方法即
package actions
import play.api.http.HeaderNames
import play.api.mvc._
import scala.concurrent.Future
/**
* Custom Action composition implementation that disables client-side browser caching
* by changing the response header of the response adding multi-browser no-cache
* parameters. The composition can be done as follows:
* {{{
*
* def link = NoCache {
* deadbolt.SubjectPresent()() { implicit request =>
* Future {
* Ok(views.html.account.link(userService, auth))
* }
* }
* }
*
* }}}
*
* @param action The inner action
* @tparam A Action type
*/
case class NoCache[A](action: Action[A]) extends Action[A] with HeaderNames {
def apply(request: Request[A]): Future[Result] = {
action(request).map { result =>
result.withHeaders(
(CACHE_CONTROL -> "no-cache, no-store, must-revalidate"),
(PRAGMA -> "no-cache"),
(EXPIRES -> "0")
)
}
}
}
现在在Play 2.6中,我遇到了很多错误,因为Action
现在需要覆盖executionContext
和parser
。在2.6中,我什么都没看到,但还有更多的复杂性……无论如何,我设法使用global
覆盖了前者,但是我没有找到为后者提供简单实现的方法。
如何为我的自定义BodyParser
指定一个我不在意的Action
?
import scala.concurrent.ExecutionContext.Implicits.global
override def executionContext = global
override val parser: BodyParser[A] = null // <<<<<< what else here?
答案 0 :(得分:3)
有一个section on the migration guide:
Scala ActionBuilder特性已被修改为将主体的类型指定为类型参数,并添加了抽象解析器成员作为默认主体解析器。您将需要修改ActionBuilders并直接传递正文解析器。
措辞可能更好,但是无论如何,您“通过正文解析器”的方式是使用依赖项注入。例如,来自actions composition docs:
test_memoization_kwarg_call
然后您将动作注入到控制器中
import play.api.mvc._
class LoggingAction @Inject() (parser: BodyParsers.Default)(implicit ec: ExecutionContext) extends ActionBuilderImpl(parser) {
override def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]) = {
Logger.info("Calling action")
block(request)
}
}
当然,您可以在class MyController @Inject()(
loggingAction: LoggingAction,
cc: ControllerComponents
) extends AbstractController(cc) {
def index = loggingAction {
Ok("Hello World")
}
}
操作中使用相同的方法:
NoCache
此外,如您所见,我们没有使用全局执行上下文,而是通过依赖项注入获得了该上下文。这是应用程序的默认执行上下文,因此如果需要,它是easier to configure。
答案 1 :(得分:2)
看一下BodyParser
的实现,可以给出BodyParser.Empty
的值
override val parser: BodyParser[A] = BodyParser.Empty
https://www.playframework.com/documentation/2.6.7/api/java/play/mvc/BodyParser.html