加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – Playframework – 请求[A] vs RequestHeader

发布时间:2020-12-16 09:57:48 所属栏目:安全 来源:网络整理
导读:我无法理解play.api.mvc.Request [A]和play.api.mvc.RequestHeader和play.api.mvc.Request [play.api.mvc.AnyContent]之间的差异. 在编译课上我有 trait Request[+A] extends scala.AnyRef with play.api.mvc.RequestHeader { def $init$() : scala.Unit = {
我无法理解play.api.mvc.Request [A]和play.api.mvc.RequestHeader和play.api.mvc.Request [play.api.mvc.AnyContent]之间的差异.

在编译课上我有

trait Request[+A] extends scala.AnyRef with play.api.mvc.RequestHeader {
  def $init$() : scala.Unit = { /* compiled code */ }
  def body : A
  def map[B](f : scala.Function1[A,B]) : play.api.mvc.Request[B] = { /* compiled code */ }
}
object Request extends scala.AnyRef {
  def apply[A](rh : play.api.mvc.RequestHeader,a : A) : scala.AnyRef with play.api.mvc.Request[A] {
  val remoteAddress : scala.Predef.String
  def username : scala.None.type
  val body : A
} = { /* compiled code */ }
}

请求[AnyContent] —> RequestWithUser [play.api.mvc.AnyContent]?

def getLoginPage[A](implicit request: Request[A],form: Form[(String,String)],msg: Option[String]): Html = {
    val req = RequestWithUser(None,request)
    views.html.secure.login(form,msg)(request = req)
  }

此代码适用于TemplatePlugin,但它在视图中不起作用:

@(loginForm: play.api.data.Form[(String,errorMsg: Option[String] = None)(implicit request: securesocial.core.RequestWithUser[_ <: play.api.mvc.AnyContent])

这不起作用,因为:

type mismatch; found : securesocial.core.RequestWithUser[A] required: securesocial.core.RequestWithUser[_ <: play.api.mvc.AnyContent]

所以我尝试将AnyContent作为泛型类型:

def getLoginPage[A](implicit request: Request[A],msg: Option[String]): Html = {
    val req = RequestWithUser[play.api.mvc.AnyContent](None,msg)(request = req)
  }

但是显示下一个编译错误:

type mismatch; found : play.api.mvc.Request[A] required: play.api.mvc.Request[play.api.mvc.AnyContent]

而play.api.mvc.AnyContent看起来像:

package play.api.mvc
sealed trait AnyContent extends scala.AnyRef {
  def $init$() : scala.Unit = { /* compiled code */ }
  def asFormUrlEncoded : scala.Option[scala.Predef.Map[scala.Predef.String,scala.Seq[scala.Predef.String]]] = { /* compiled code */ }
  def asText : scala.Option[scala.Predef.String] = { /* compiled code */ }
  def asXml : scala.Option[scala.xml.NodeSeq] = { /* compiled code */ }
  def asJson : scala.Option[play.api.libs.json.JsValue] = { /* compiled code */ }
  def asMultipartFormData : scala.Option[play.api.mvc.MultipartFormData[play.api.libs.Files.TemporaryFile]] = { /* compiled code */ }
  def asRaw : scala.Option[play.api.mvc.RawBuffer] = { /* compiled code */ }
}

请帮我解决这个问题.

编辑 – 到目前为止的解决方案

我找到了编译甚至运行良好的代码.不过这不是优雅的方式,因为我使用了asInstanceOf和cast类.

def getLoginPage[A](implicit request: Request[A],msg: Option[String]): Html = {
    implicit val r = RequestWithUser[play.api.mvc.AnyContent](None,request.asInstanceOf[Request[AnyContent]])
    views.html.secure.login(form,msg)(request = r)
  }

解决方法

RequestHeader表示HTTP请求的标头. Request [A]是一个RequestHeader加上A的解析请求体.Play中的默认体解析器检测一些众所周知的体格式(application / json,application / xml,text / plain,application / x-www-form-urlencoded,multipart / form-data),并自动将它们解析为AnyContent类型的主体,然后允许您通过调用asJson等方法来访问特定类型.如果你写一个像这样的动作:

def myAction = Action { req =>
  ...
}

然后req的类型将是Request [AnyContent].另一方面,如果您明确指定了一个主体解析器,那么请求的类型将是该主体解析器返回的类型,例如:

def myAction = Action(parse.json) { req =>
  ...
}

在这种情况下,req将是Request [JsValue].因此,安全社交模板需要Request [AnyContent],因此首先,这意味着您只能从使用默认主体解析器的操作中使用它.接下来,这意味着您必须将getLoginPage的签名更改为仅接受Request [AnyContent],例如:

def getLoginPage(implicit request: Request[AnyContent],msg: Option[String]): Html = {
  val req = RequestWithUser(None,request)
  views.html.secure.login(form,msg)(request = req)
}

这应该按原样工作,只要调用getLoginPage的每个操作都有一个由默认主体解析器生成的请求.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读