首页 文章

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

提问于
浏览
1

我正在尝试使用动作合成将假用户添加到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 回答

  • 5

    你几乎就在那里 - 但是为了从你的Action组合中获得最大 Value ,你应该能够让你的"client"动作完全不知道会话 - 毕竟他们真的只关心 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() .

相关问题