在Play中有它们什么不同?
如果你不得不为多条HTTP请求保存数据,你能够将这些数据存入Session或者Flash的作用域中。在用户的整个会话过程中存在Session中的数据都是可用的,或者将用户数据存入Flash作用域中直到用户发出下一个请求时。
在使用Play的Cookie机制时,明白Session和Fliash所存储的数据并不是存储在服务器端,而是被附加在每一次后随后发来的HTTP请求中非常重要的。这意味着存储的数据非常有限(4KB),因此在该空间内往往只能存储字符串类型的数据。在Play框架中Cookie的默认名字为PLAY_SESSION。这个名字可以通过设置application.conf中的session.cookieName字段进行改变。
如果Cookie的名称被改变了,那么仍然可以利用前文中提到的方法修改响应中的Cookie字段。
当然了,存储在用户端的Cookie是经过使用配置文件中的安全码进行加密处理的。这样想要在客户端修改Cookie已达到入侵的可能性就十分小了。
Play的Session并不用该被当作缓存使用。如果需要缓存一些数据相关到特定的Session,可以使用Play内置的缓存机制并且为每个特定用户保存一个用户唯一ID。
Session机制不涉及超时,通常来说直到用户关闭浏览器时才会释放Session。如果需要一个手动的设置的超时控制,那么可以在用户的Session中存放一个时间戳用来计时。
(这点在tomcat中一般30分钟是默认的Session释放时间。当然,Play的Session机制本来就不同)
在PlaySession中存储数据
Play的Session是一个Cookie,也可以将其看作是一个HTTP的header。那么在操作Session时可以和操作其他HTTP Header一样来进行操作。
Ok("Welcome!").withSession(
"connected" -> "user@gmail.com")
值得注意的是,这样来操作Session会将重置所有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的方法就是重建一个空的Session替代它。
Ok("Bye").withNewSession
Play操作Flash作用域
Flash作用的工作机制与Session很相似,但是也有一些不同:
- 数据的存储只在当次请求中有用,下次的请求长连接中不包含本次的数据相关信息;
- Flash的Cookie是非加密的,这样方便用户对这些数据进行修改。
特别注意:Flash作用的Cookie应当只有在non-Ajax环境下用于传输“Success/error”消息。作为用于传递至下次请求的数据,由于在复杂的网络环境中缺乏安全性的保证,Flash作用域通常是不推荐使用的。
以下是一些关于Flash作用域的使用方式:
def index = Action { implicit request =>
Ok {
request.flash.get("success").getOrElse("Welcome!")
}
}
def save = Action {
Redirect("/home").flashing(
"success" -> "The item has been created")
读取Flash作用域存储的值时,只需要添加一个隐式的转换 :
@()(implicit flash: Flash) ... @flash.get("success").getOrElse("Welcome!") ...
如果在执行以上方法时返回了‘could not find implicit value for parameter flash: play.api.mvc.Flash‘,那说明在Action定义时没有引入request对象。此时可以添加’implicit request=>‘来解决:
def index() = Action {
implicit request =>
Ok(views.html.Application.index())
}