§会话和闪存范围
§Play 中的不同之处
如果您需要在多个 HTTP 请求之间保留数据,可以将它们保存在会话或闪存范围内。存储在会话中的数据在整个用户会话期间可用,而存储在闪存范围中的数据仅在下一个请求中可用。
§使用 Cookie
重要的是要了解会话和闪存数据不是存储在服务器中,而是使用 HTTP Cookie 添加到每个后续 HTTP 请求中。
由于会话和闪存是使用 Cookie 实现的,因此有一些重要的影响。
- 数据大小非常有限(最多 4 KB)。
- 您只能存储字符串值,尽管您可以将 JSON 序列化到 Cookie 中。
- Cookie 中的信息对浏览器可见,因此可能会暴露敏感数据。
- Cookie 信息对于原始请求是不可变的,并且仅对后续请求可用。
最后一点可能会造成混淆。当您修改 Cookie 时,您是在向响应提供信息,Play 必须再次解析它以查看更新的值。如果您想确保会话信息是最新的,那么您应该始终将会话修改与重定向配对。
§会话配置
Cookie 的默认名称是 PLAY_SESSION
。这可以通过在 application.conf 中配置键 play.http.session.cookieName
来更改。
如果 Cookie 的名称更改,可以使用 设置和丢弃 Cookie 中提到的相同方法丢弃之前的 Cookie。
有关如何在 application.conf
中配置会话 Cookie 参数的更多信息,请参阅 配置会话 Cookie。
§会话超时/过期
默认情况下,会话没有技术超时。它在用户关闭 Web 浏览器时过期。如果您需要特定应用程序的功能超时,可以通过在 application.conf
中配置键 play.http.session.maxAge
来设置会话 Cookie 的最大生存期,这也会将 play.http.session.jwt.expiresAfter
设置为相同的值。maxAge
属性将从浏览器中删除 Cookie,并且 JWT exp
声明将设置在 Cookie 中,并在给定持续时间后使其失效。有关更多信息,请参阅 配置会话 Cookie。
§在会话中存储数据
由于会话只是一个 Cookie,它也只是一个 HTTP 标头。您可以像操作其他结果属性一样操作会话数据。
Redirect("/home").withSession("connected" -> "[email protected]")
请注意,这将替换整个会话。如果您需要向现有会话添加元素,只需向传入会话添加元素,并将其指定为新会话。
Redirect("/home").withSession(request.session + ("saidHello" -> "yes"))
您可以通过相同的方式从传入会话中删除任何值。
Redirect("/home").withSession(request.session - "theme")
§读取会话值
您可以从 HTTP 请求中检索传入会话。
def index: Action[AnyContent] = Action { request =>
request.session
.get("connected")
.map { user => Ok("Hello " + user) }
.getOrElse {
Unauthorized("Oops, you are not connected")
}
}
§丢弃整个会话
有一个特殊操作可以丢弃整个会话。
Redirect("/home").withNewSession
§闪存范围
闪存范围的工作原理与会话完全相同,但有一个区别。
- 数据只保留一个请求。
重要提示:闪存范围仅应用于在简单的非 Ajax 应用程序上传输成功/错误消息。由于数据仅保留到下一个请求,并且没有保证在复杂的 Web 应用程序中确保请求顺序,因此闪存范围容易受到竞争条件的影响。
以下是一些使用闪存范围的示例。
def index: Action[AnyContent] = Action { implicit request =>
Ok {
request.flash.get("success").getOrElse("Welcome!")
}
}
def save: Action[AnyContent] = Action {
Redirect("/home").flashing("success" -> "The item has been created")
}
要在视图中检索 Flash 范围值,请添加一个隐式 Flash 参数
@()(implicit flash: Flash)
...
@flash.get("success").getOrElse("Welcome!")
...
在您的 Action 中,指定一个 implicit request =>
,如下所示
def index: Action[AnyContent] = Action { implicit request => Ok(views.html.index()) }
将根据隐式请求向视图提供一个隐式 Flash。
如果出现错误“无法为参数 flash 找到隐式值:play.api.mvc.Flash”,则这是因为您的 Action 范围中没有隐式请求。
下一步:正文解析器
发现此文档中的错误?此页面的源代码可以在 此处 找到。阅读完 文档指南 后,请随时贡献拉取请求。有疑问或建议要分享?请访问 我们的社区论坛,与社区开始对话。