为Scala播放2.2:是否可以修改传入请求的会话?

时间:2013-12-01 21:23:42

标签: scala playframework playframework-2.2

我正在尝试使用动作合成将假用户添加到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中没有这样的方法。

为了解决这个问题,您会建议什么?

1 个答案:

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