I'm unable to understand diffrence between play.api.mvc.Request[A]
and play.api.mvc.RequestHeader
and play.api.mvc.Request[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)
}
@(loginForm: play.api.data.Form[(String,String)], errorMsg: Option[String] = None)(implicit request: securesocial.core.RequestWithUser[_ <: play.api.mvc.AnyContent])
This code works in TemplatePlugin
but it's not working in view:
type mismatch; found : securesocial.core.RequestWithUser[A] required: securesocial.core.RequestWithUser[_ <: play.api.mvc.AnyContent]
It's not working because:
def getLoginPage[A](implicit request: Request[A], form: Form[(String, String)], msg: Option[String]): Html = {
val req = RequestWithUser[play.api.mvc.AnyContent](None, request)
views.html.secure.login(form, msg)(request = req)
}
So I tried to put AnyContent
as generic type:
type mismatch; found : play.api.mvc.Request[A] required: play.api.mvc.Request[play.api.mvc.AnyContent]
But next compilation error shown:
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 */ }
}
And play.api.mvc.AnyContent looks like:
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 */ } }
Please help me to solve this problem.
asInstanceOf
and cast class.
def getLoginPage[A](implicit request: Request[A], form: Form[(String, String)], 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
represents the header of the HTTP request. Request[A]
is a RequestHeader
plus a parsed request body of A
. The default body parser in Play detects a few well known body formats ( application/json
, application/xml
, text/plain
, application/x-www-form-urlencoded
, multipart/form-data
), and parses them automatically into a body of type AnyContent
, which then lets you access the specific types by calling methods such as asJson
. If you write an action like:
def myAction = Action { req =>
...
}
Then the type of req
will be Request[AnyContent]
. On the other hand, if you explicitly specify a body parser, then the type of the request will be the type that that body parser returns, for example:
def myAction = Action(parse.json) { req =>
...
}
In that case, req
will be Request[JsValue]
. So, the secure social template wants a Request[AnyContent]
, so firstly, this means you can only use it from actions that use the default body parser. Next, it means that you have to change the signature of your getLoginPage
to only accept Request[AnyContent]
, eg:
def getLoginPage(implicit request: Request[AnyContent], form: Form[(String, String)], msg: Option[String]): Html = {
val req = RequestWithUser(None, request)
views.html.secure.login(form, msg)(request = req)
}
That should work as is, as long as every action that invokes getLoginPage
has a request that has been produced by the default body parser.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.