我正在尝试使用动作合成将假用户添加到Session。
def GuestAction(f: Request[AnyContent] => Result): Action[AnyContent] = {
Action { request =>
var myUser = searchUser(request.session)
if ( myUser == null ) {
myUser = newUser()
}
f(request).withSession("user" -> myUser)
}
}
在我的控制器中有
def action1 = GuestAction { implicit request =>
// My code
Ok()
}
def action2 = GuestAction { implicit request =>
val user = request.session.get("user").get
// My code
Ok()
}
当我打开Chrome浏览器并浏览指向“action1”的路线然后浏览指向“action2”的路线时,一切正常:我有一个新用户并且它已附加到会话中。
相反,当我打开Chrome并首先浏览指向“action2”的路径时,我收到错误,因为我的“request.session”为空,这很明显:使用.withSession()
会话附加到Result
,而不是传入的请求。
因此,为了使这项工作,我需要将会话密钥/值对附加到传入请求 - 就像FakeRequest.withSession()
中可能的那样,但Request
中没有这样的方法。
为了解决这个问题,您会建议什么?
答案 0 :(得分:5)
你几乎就在那里 - 但是为了从你的动作作品中获得最大价值,你应该能够让你的"客户"操作完全没有意识到会话 - 毕竟他们真的只关心User
对象。你希望能够写下:
def action2 = GuestAction { implicit user => implicit request =>
// Do something with 'user', whether it's a guest or real
println(s"My user is $user")
Ok()
}
action2
并不关心如何获得User
,但它可以依赖于一个可用的GuestAction
。为了实现这一点,def GuestAction(f: (User) => Request[AnyContent] => Result): Action[AnyContent] = {
Action { request =>
var myUser = searchUser(request.session)
if ( myUser == null ) {
myUser = newUser()
}
f(myUser)(request)
}
}
必须是这样的:
response.withSession()
唯一剩下的难题是让用户加入会话 - 作为成功登录过程的一部分,您仍然可以使用传统的{{1}}。