session和flash scope 的区别
如果需要通过多个HTTP请求传输数据,那么就要用到session和flash
scope。在session中存储的,整个会话过程都有效,在flash scope
中存储的,只是对下一个请求有效。服务器不存储session和flash
scope中的数据,它们只是被传递给了下一个请求,使用Cookies机制。这就意味着你只能存储字符串类型,而且大小有限,最多4KB。Cookies的默认名字是PLAY_SESSION,通过application.conf中的session.cookieName可以修改。
cookie的数据被标记了一个密钥,因此客户端无法修改Cookies的数据,否则数据会被判无效。
Play Session不被用来作为缓存,如果需要缓存一些和session相关的数据,就要使用play内置的缓存机制,在用户的session中存储一个unique ID来保持和特定用户的关联。
Session默认没有失效时间,除非用户关掉浏览器。如果需要设定失效时间,就要在用户session中存储一个时间戳,不管application是否需要。可以在application.conf中通过play.http.session.maxAge设置最长的失效时间,但也不能防止黑客恢复过了有效期的Cookies。
在Session中存储数据
由于Session只是Cookie,同时也只是一个HTTP的头部,你可以用与处理请求结果相同的方式处理session的数据:
Ok("Welcome!").withSession( "connected" -> "user@gmail.com")
在已有的session中添加一个元素,并且生成新session的方式如下:
Ok("Hello World!").withSession( request.session + ("saidHello" -> "yes"))
删除session中的元素也是用类似的方式:
Ok("Theme reset!").withSession( request.session - "theme")
读取Session的值
从HTTP请求中搜索Session:
def index = Action { request => request.session.get("connected").map { user => Ok("Hello " + user) }.getOrElse { Unauthorized("Oops, you are not connected") }}
丢弃整个Session
以下操作可以丢弃整个Session:
Ok("Bye").withNewSession
Flash Scope
Flash Scope的工作方式和Session有两点不同:
数据只在一个请求中保留,另一点是Flash cookie没有标记,用户可以修改它。
Flash scope只能在没有Ajax的applications中传输success/error信息,由于数据只在一个请求中并且在复杂web应用中不能保证请求的顺序,因此它受到竞争条件的约束。
使用Flash scope的例子如下:
def index = Action { implicit request => Ok { request.flash.get("success").getOrElse("Welcome!") }}def save = Action { Redirect("/home").flashing( "success" -> "The item has been created")}
在view中搜索Flash scope的值,并且添加隐式的Flash参数,具体操作如下:
@()(implicit flash: Flash)...@flash.get("success").getOrElse("Welcome!")...
然后在Action中隐式指定implicit request =>,通过如下方式:
def index = Action { implicit request => Ok(views.html.index())}
基于隐式的请求,一个隐式的Flash会被提供给view。
如果报了如下错误:
‘could not find implicit value for parameter flash: play.api.mvc.Flash’
那说明你的Action在范围内没有隐式的请求。