迁移至2.6如何获得我不在乎的BodyParser?

时间:2019-05-07 10:47:41

标签: scala playframework playframework-2.6

在Play 2.6之前,我有一些自定义操作,例如我只需关心实现apply方法即

的NoCache动作
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现在需要覆盖executionContextparser。在2.6中,我什么都没看到,但还有更多的复杂性……无论如何,我设法使用global覆盖了前者,但是我没有找到为后者提供简单实现的方法。

如何为我的自定义BodyParser指定一个我不在意的Action

import scala.concurrent.ExecutionContext.Implicits.global

override def executionContext = global
override val parser: BodyParser[A] = null // <<<<<< what else here?

2 个答案:

答案 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