【问题标题】:override and with generic type parameter覆盖并使用泛型类型参数
【发布时间】:2016-06-28 19:58:03
【问题描述】:

我正在使用 Play Scala 2.5,我想知道如何重写 invokeBlock 方法,以便我可以将请求正文作为 json 获取。

case class AuthenticatedRequest[A](val username: Option[String], val param: Option[String], request: Request[A]) extends WrappedRequest[A](request)

object AuthenticatedAction extends ActionBuilder[AuthenticatedRequest] {

    /**
     * logger used to log actions.
     */
    val logger: Logger = Logger("mylogger")

    def invokeBlock[A](request: Request[A], block: AuthenticatedRequest[A] => Future[Result]): Future[Result] = {
        request.session.get("username") match {
            case Some(username) => { 
                val param = (request.body.asJson.get \ "param").as[String]
                block(new AuthenticatedRequest(Some(username), Some(param), request)) 
            }
            case None => Future.successful(Results.Forbidden)
        }
    }
}

编译后我必须遵循异常:

value asJson is not a member of type parameter A
[error]                 val param = (request.body.asJson.get \ "param").as[String]

【问题讨论】:

  • 您的请求是否有标头Content-Type: application/json
  • 是的,它确实包含 Content-Type: application/json

标签: scala playframework


【解决方案1】:

该错误与您的 body 正在返回泛型类型 A 的事实有关,而未定义 asJson 方法。

不幸的是,由于 Scala 的类型擦除,您不能直接使用模式匹配来获取 A 的类型(在运行时,只有类存在,而不是它的类型参数)。一种解决方法是使用反射 API,如下所示:

    import scala.reflect.runtime.universe._
    def invokeBlock[A](request: Request[A]) = {
        request match {
            case specificRequest : Request[SpecificRequest] if (typeOf[A] =:= typeOf[SpecificRequest]) => // Do the request processing
        }
}

这应该允许您检索类型,并能够调用它的特定方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-12
    • 2012-09-09
    • 2018-06-20
    • 2020-06-03
    • 1970-01-01
    • 2020-07-16
    相关资源
    最近更新 更多