【二 HTTP編程】4. Session和Flash做用域

Play的特殊之處

當你須要跨多個HTTP請求來共享數據時,你能夠將它們保存在Session或者Flash域中。Session中的數據在user Session整個週期有效,而Flash域中的數據僅僅保存至下一個request請求。html

很重要的一個概念,是Session和Flash的數據並不禁服務器保存,而是在各個HTTP請求中被添加到cookie裏。這意味着數據量不能太大(小於4Kb)並且僅僅只能保存String格式的數據。默認的cookie名稱是 PLAY_SESSION。固然你能夠在 application.conf 中修改 play.http.session.cookieName來改變默認值。web

若是cookie名稱被改變了,先前的cookie能夠經過上一章提到過的方法來刪除。編程

固然,cookie的值由一個secret簽名來保證不被客戶端修改(不然cookie將會失效)。api

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同樣操做它:cookie

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

注意上面的操做會替換整個session,若是你只是須要向一個已有的Session添加一個元素,你能夠在傳入的Session中添加一個元素,而後將它指定爲一個新的Session:session

Ok("Hello World!").withSession(request.session + ("saidHello" -> "yes"))

你也能夠經過這種方式來從Session中刪除數據:mvc

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。

相關文章
相關標籤/搜索