從零開始的Spring Session(二)

從零開始的Spring Session(一) 中介紹了一些Session和Cookie的基礎知識,這篇文章開始正式介紹Spring Session是如何對傳統的Session進行改造的。官網這麼介紹Spring Session:
Spring Session provides an API and implementations for managing a user’s session information. It also provides transparent integration with:web

HttpSession - allows replacing the HttpSession in an application container (i.e. Tomcat) neutral way. Additional features include:
 
Clustered Sessions - Spring Session makes it trivial to support clustered sessions without being tied to an application container specific solution.
Multiple Browser Sessions - Spring Session supports managing multiple users' sessions in a single browser instance (i.e. multiple authenticated accounts similar to Google).
RESTful APIs - Spring Session allows providing session ids in headers to work with RESTful APIs
WebSocket - provides the ability to keep the HttpSession alive when receiving WebSocket messages
其具體的特性很是之多,具體的內容能夠從文檔中瞭解到,筆者作一點本身的總結,Spring Session的特性包括但不限於如下:redis

使用GemFire來構建C/S架構的httpSession(不關注)
使用第三方倉儲來實現集羣session管理,也就是常說的分佈式session容器,替換應用容器(如tomcat的session容器)。倉儲的實現,Spring Session提供了三個實現(redis,mongodb,jdbc),其中redis使咱們最經常使用的。程序的實現,使用AOP技術,幾乎能夠作到透明化地替換。(核心)
能夠很是方便的擴展Cookie和自定義Session相關的Listener,Filter。
能夠很方便的與Spring Security集成,增長諸如findSessionsByUserName,rememberMe,限制同一個帳號能夠同時在線的Session數(如設置成1,便可達到把前一次登陸頂掉的效果)等等
介紹完特性,下面開始一步步集成Spring Sessionspring

使用Redis集成Spring Sessionmongodb

引入依賴,Spring Boot的版本採用1.5.4
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>
配置
配置類開啓Redis Http Sessionchrome

@Configuration
@EnableRedisHttpSession
public class HttpSessionConfig {
}
基本是0配置,只須要讓主配置掃描到@EnableRedisHttpSession便可瀏覽器

配置文件application.yml,配置鏈接的redis信息tomcat

spring:
  redis:
    host: localhost
    port: 6379
    database: 0
編寫測試Controller,以便於觀察Spring Session的特性,和前一篇文章使用一樣的代碼
@Controller
public class CookieController {
    @RequestMapping("/test/cookie")
    public String cookie(@RequestParam("browser") String browser, HttpServletRequest request, HttpSession session) {
        //取出session中的browser
        Object sessionBrowser = session.getAttribute("browser");
        if (sessionBrowser == null) {
            System.out.println("不存在session,設置browser=" + browser);
            session.setAttribute("browser", browser);
        } else {
            System.out.println("存在session,browser=" + sessionBrowser.toString());
        }
        Cookie[] cookies = request.getCookies();
        if (cookies != null && cookies.length > 0) {
            for (Cookie cookie : cookies) {
                System.out.println(cookie.getName() + " : " + cookie.getValue());
            }
        }
        return "index";
    }
}
啓動類省略,下面開始測試。cookie

在瀏覽器中訪問以下端點: http://localhost:8080/test/cookie?browser=chrome,下面是連續訪問4次的結果session

1    不存在session,設置browser=chrome
2    存在session,browser=chrome
    SESSION : 70791b17-83e1-42db-8894-73fbd2f2a159
3    存在session,browser=chrome
    SESSION : 70791b17-83e1-42db-8894-73fbd2f2a159
4    存在session,browser=chrome
    SESSION : 70791b17-83e1-42db-8894-73fbd2f2a159
若是還記得上一篇文章中運行結果的話,會發現和原生的session管理是有一些差異,原先的信息中咱們記得Cookie中記錄的Key值是JSESSIONID,而替換成RedisHttpSession以後變成了SESSION。接着觀察redis中的變化:數據結構

解析一下這個redis store,若是不糾結於細節,能夠跳過,不影響使用。

  1. spring:session是默認的Redis HttpSession前綴(redis中,咱們經常使用':'做爲分割符)。
  2. 每個session都會有三個相關的key,第三個key最爲重要,它是一個HASH數據結構,將內存中的session信息序列化到了redis中。如上文的browser,就被記錄爲sessionAttr:browser=chrome,還有一些meta信息,如建立時間,最後訪問時間等。
  3. 另外兩個key,expirations:1504446540000和sessions:expires:7079...我發現大多數的文章都沒有對其分析,前者是一個SET類型,後者是一個STRING類型,可能會有讀者發出這樣的疑問,redis自身就有過時時間的設置方式TTL,爲何要額外添加兩個key來維持session過時的特性呢?這須要對redis有必定深刻的瞭解才能想到這層設計。固然這不是本節的重點,簡單提一下:redis清除過時key的行爲是一個異步行爲且是一個低優先級的行爲,用文檔中的原話來講即是,可能會致使session不被清除。因而引入了專門的expiresKey,來專門負責session的清除,包括咱們本身在使用redis時也須要關注這一點。在開發層面,咱們僅僅須要關注第三個key就好了。

總結

本節主要講解了Spring Boot如何集成Spring Session,下一節將介紹更加複雜的特性。包括自定義Cookie序列化策略,與Spring Security的集成,根據用戶名查找session等特性以及使用注意點。

相關文章
相關標籤/搜索