【二 HTTP编程】4. Session和Flash作用域

Play的特殊之处

当你需要跨多个HTTP请求来共享数据时,你可以将它们保存在Session或者Flash域中。Session中的数据在user Session整个周期有效,而Flash域中的数据仅仅保存至下一个request请求。

很重要的一个概念,是Session和Flash的数据并不由服务器保存,而是在各个HTTP请求中被添加到cookie里。这意味着数据量不能太大(小于4Kb)而且仅仅只能保存String格式的数据。默认的cookie名称是 PLAY_SESSION。当然你可以在 application.conf 中修改 play.http.session.cookieName来改变默认值。

如果cookie名称被改变了,先前的cookie可以通过上一章提到过的方法来删除。

当然,cookie的值由一个secret签名来保证不被客户端修改(否则cookie将会失效)。

Play Session并不是用来当做缓存的。如果你需要将某些数据缓存到关联的Session中,你可以使用Play内置的缓存机制,并在用户Session中保存关联用户缓存的唯一ID。

Session设置

请移步Configuring Session Cookies查看application.conf中session cookie的更多设置。

Session超时/失效

默认的,Session没有超时时间。它将在用户关闭浏览器时失效。如果你需要一个可编程的超时时间,可以通过在 application.conf 设置 play.http.session.maxAge 来限定,此配置会将 play.http.session.jwt.expiresAfter 设置为同样的值。maxAge 将从浏览器移除cookie,同时JWT的 exp 将在cookie中被设置,并在超时后将其失效。移步这里查看更多信息。

在Session中保存数据

Session仅仅是一个Cookie而已,因此它也是一个HTTP Header。你可以像操作其他Header一样操作它:

Ok("Welcome!").withSession(
    "connected" -> "user@gmail.com")

注意上面的操作会替换整个session,如果你只是需要向一个已有的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 { requset =>
    request.session.get("connected").map { user =>
        Ok("Hello " + user)
    }.getOrElse {
        Unauthorized("Oops, you are not connected")
    }
}

丢弃整个Session

有一个特殊的方法来丢弃整个Session:

Ok("Bye").withNewSession

Flash域

Flash几乎和Session一模一样,只有两点区别:

  • 数据仅仅保存一个request
  • Flash cookie没有被签名,便于用户修改

重要: Flash域应该仅仅在非Ajax应用中传递success/error消息。因为在复杂的web应用中没有任何request顺序的保证,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")
}

你可以增加一个implicit的Flash参数,以便在view中获取Flash域的值:

@()(implicit flash: Flash)
...
@flash.get("success").getOrElse("Welcome!")
...

并在Action中,指定一个 implicit request => :

def index = Action { implicit request =>
    Ok(views.html.index())
}

一个隐式的Flash将在view中随着隐式的request一起提供。

如果看到'could not find implicit value for parameter flash: play.api.mvc.Flash' 的错误提示,说明你的Action在当前域没有找到隐式的request。

转载于:https://my.oschina.net/landas/blog/1927251

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值