最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Session的使用示例

 更新時(shí)間:2021年06月19日 17:17:07   作者:wowojyc藝超  
最近團(tuán)隊(duì)一個(gè)項(xiàng)目需要使用Session,之前沒(méi)有在實(shí)際項(xiàng)目中使用過(guò)Spring-Session,這里記錄一下使用的過(guò)程

Session

Http協(xié)議是無(wú)狀態(tài)的,這樣對(duì)于服務(wù)端來(lái)說(shuō),沒(méi)有辦法區(qū)分是新的訪(fǎng)客還是舊的訪(fǎng)客。但是,有些業(yè)務(wù)場(chǎng)景,需要追蹤用戶(hù)多個(gè)請(qǐng)求,此時(shí)就需要Session。關(guān)于session的百度百科session

Session:在計(jì)算機(jī)中,尤其是在網(wǎng)絡(luò)應(yīng)用中,稱(chēng)為“會(huì)話(huà)控制”。Session對(duì)象存儲(chǔ)特定用戶(hù)會(huì)話(huà)所需的屬性及配置信息。這樣,當(dāng)用戶(hù)在應(yīng)用程序的Web頁(yè)之間跳轉(zhuǎn)時(shí),存儲(chǔ)在Session對(duì)象中的變量將不會(huì)丟失,而是在整個(gè)用戶(hù)會(huì)話(huà)中一直存在下去。當(dāng)用戶(hù)請(qǐng)求來(lái)自應(yīng)用程序的 Web頁(yè)時(shí),如果該用戶(hù)還沒(méi)有會(huì)話(huà),則Web服務(wù)器將自動(dòng)創(chuàng)建一個(gè) Session對(duì)象。當(dāng)會(huì)話(huà)過(guò)期或被放棄后,服務(wù)器將終止該會(huì)話(huà)

核心特點(diǎn):

  1. 服務(wù)端存儲(chǔ)
  2. 會(huì)過(guò)期

Session常用解決方案

對(duì)于Session的常用解決方案,可以劃分為三種。

  • 負(fù)載均衡方式

借助負(fù)載均衡設(shè)備或者模塊,將指定的Session始終路由到同一臺(tái)機(jī)器即可,如Nginx。

  • 副本復(fù)制方式

利用服務(wù)器節(jié)點(diǎn)間的副本復(fù)制方式,保證集群所有節(jié)點(diǎn)擁有的Session數(shù)據(jù)一致。

  • 集中存儲(chǔ)方式

引入第三方存儲(chǔ),將Session數(shù)據(jù)集中存儲(chǔ)到外部存儲(chǔ)中,如Redis或者數(shù)據(jù)庫(kù)等。

本文介紹的Spring-Session是采用第三種,集中存儲(chǔ)的方式。

Spring-Session

核心組成模塊

  • Spring Session Core

提供Spring Session核心的功能和API

  • Spring Session Data Redis

提供基于Redis的SessionRepository以及配置

  • Spring Session JDBC

提供基于關(guān)系型數(shù)據(jù)庫(kù)的SessionRepository以及配置

  • Spring Session Hazelcast

提供基于Hazelcast的SessionRepository以及配置

測(cè)試代碼

controller提供三個(gè)接口,分別對(duì)應(yīng)Session的獲取、保存和清理

@GetMapping("/")
public String process(Model model, HttpSession session) {
  @SuppressWarnings("unchecked")
  List<String> messages = (List<String>) session.getAttribute("springSession");

  if (messages == null) {
    messages = new ArrayList<>();
  }
  model.addAttribute("sessionMessages", messages);

  return "sessionTest";
}

@PostMapping("/persistSession")
public String persistMessage(@RequestParam("msg") String msg, HttpServletRequest request) {
  @SuppressWarnings("unchecked")
  List<String> messages = (List<String>) request.getSession().getAttribute("springSession");
  if (messages == null) {
    messages = new ArrayList<>();
    request.getSession().setAttribute("springSession", messages);
  }
  messages.add(msg);
  request.getSession().setAttribute("springSession", messages);
  return "redirect:/";
}

@PostMapping("/destroySession")
public String destroySession(HttpServletRequest request) {
  request.getSession().invalidate();
  return "redirect:/";
}

sessionTest.html對(duì)應(yīng)頁(yè)面操作

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Spring Boot Session Example</title>
</head>
<body>
<div>
    <form th:action="@{/persistSession}" method="post">
        <textarea name="msg" cols="40" rows="2"></textarea>
        <br> <input type="submit" value="保存" />
    </form>
</div>
<div>
    <h2>session列表</h2>
    <ul th:each="message : ${sessionMessages}">
        <li th:text="${message}">message</li>
    </ul>
</div>

<div>
    <form th:action="@{/destroySession}" method="post">
        <input type="submit" value="清空" />
    </form>
</div>
</body>
</html>

基于數(shù)據(jù)庫(kù)的Spring-Session

1.引入maven依賴(lài)

使用MySQL存儲(chǔ),所以引入了MySQL。

涉及到SpringBoot JDBC的配置,引入了Spring Boot JDBC Starter。

<dependency>
  <groupId>org.springframework.session</groupId>
  <artifactId>spring-session-core</artifactId>
  <version>2.5.0</version>
</dependency>

<dependency>
  <groupId>org.springframework.session</groupId>
  <artifactId>spring-session-jdbc</artifactId>
  <version>2.5.0</version>
</dependency>

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>8.0.18</version>
</dependency>

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

注意:

No session repository could be auto-configured, check your configuration (session store type is 'jdbc')

如果存在這個(gè)報(bào)錯(cuò),是因?yàn)闆](méi)有引入spring-boot-starter-jdbc,引入即可。

2.配置application.properties文件

主要包含兩部分,數(shù)據(jù)庫(kù)的配置以及Spring Session Jdbc配置。

# 配置數(shù)據(jù)源相關(guān)內(nèi)容
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/spring_learn?createDatabaseIfNotExist=true&autoReconnect=true&useSSL=false
spring.datasource.username=xxx
spring.datasource.password=xxx
spring.datasource.initialization-mode=always

# session類(lèi)型選擇jdbc
spring.session.store-type=jdbc
spring.session.jdbc.initialize-schema=always
# 指定表名
#spring.session.jdbc.table-name=SESSIONS
# 超時(shí)時(shí)間
spring.session.timeout=180s

3.數(shù)據(jù)庫(kù)存儲(chǔ)解析

默認(rèn)情況下,數(shù)據(jù)庫(kù)中會(huì)創(chuàng)建2張表。SPRING_SESSION和SPRING_SESSION_ATTRIBUTION。

SPRING_SESSION用于存在session自身的一些屬性,如創(chuàng)建時(shí)間、過(guò)期時(shí)間等,詳細(xì)schema如下。

CREATE TABLE `SPRING_SESSION` (
  `PRIMARY_ID` char(36) NOT NULL,
  `SESSION_ID` char(36) NOT NULL,
  `CREATION_TIME` bigint NOT NULL,
  `LAST_ACCESS_TIME` bigint NOT NULL,
  `MAX_INACTIVE_INTERVAL` int NOT NULL,
  `EXPIRY_TIME` bigint NOT NULL,
  `PRINCIPAL_NAME` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`PRIMARY_ID`),
  UNIQUE KEY `SPRING_SESSION_IX1` (`SESSION_ID`),
  KEY `SPRING_SESSION_IX2` (`EXPIRY_TIME`),
  KEY `SPRING_SESSION_IX3` (`PRINCIPAL_NAME`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC

SPRING_SESSION_ATTRIBUTION用于存儲(chǔ)session相關(guān)聯(lián)的屬性,schema如下。

CREATE TABLE `SPRING_SESSION_ATTRIBUTES` (
  `SESSION_PRIMARY_ID` char(36) NOT NULL,
  `ATTRIBUTE_NAME` varchar(200) NOT NULL,
  `ATTRIBUTE_BYTES` blob NOT NULL,
  PRIMARY KEY (`SESSION_PRIMARY_ID`,`ATTRIBUTE_NAME`),
  CONSTRAINT `SPRING_SESSION_ATTRIBUTES_FK` FOREIGN KEY (`SESSION_PRIMARY_ID`) REFERENCES `SPRING_SESSION` (`PRIMARY_ID`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC

4.測(cè)試執(zhí)行

SPRING_SESSION中的數(shù)據(jù)

SPRING_SESSION_ATTRIBUTION中的數(shù)據(jù)。

基于Redis的Spring-Session

幾乎同樣的步驟

maven依賴(lài)

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<dependency>
  <groupId>org.springframework.session</groupId>
  <artifactId>spring-session-data-redis</artifactId>
</dependency>

application.properties配置

spring.session.store-type=redis
spring.redis.host=127.0.0.1
spring.redis.port=6379

結(jié)果分析

一次請(qǐng)求后,多了三個(gè)屬性,分析如下。

key 類(lèi)型 用途 value
spring:session:sessions:expires:${sessionId} string 判斷sesssion是否存在
spring:session:sessions:${sessionId} hash session相關(guān)的屬性,包括有效期、創(chuàng)建時(shí)間、具體屬性等 creationTime/lastAccessedTime/sessionAttr/maxInactiveInterval
spring:session:expirations:1623656160000 set 存儲(chǔ)待過(guò)期的sessionId列表 key: 過(guò)期的時(shí)間戳;value: 在這個(gè)時(shí)間戳將要過(guò)期的expire key列表。

在訪(fǎng)問(wèn)時(shí),先通過(guò)第一個(gè)key,判斷session是否存在以及是否過(guò)期。如果沒(méi)有過(guò)期,可以通過(guò)第二個(gè)key獲取或者更新對(duì)應(yīng)的session詳情。

對(duì)于第三個(gè)key,實(shí)際上Spring-Session-Redis會(huì)有特殊的用途,主要是為了Redis的keySpace-notificationhttps://redis.io/topics/notifications。核心目的是為了確保過(guò)期的session一定要觸發(fā)過(guò)期事件。關(guān)于這方面的解釋?zhuān)梢钥匆幌翿edisIndexedSessionRepository中的注釋。

訂閱Spring-Session的相關(guān)事件

有些時(shí)候,我們比較關(guān)心Session的創(chuàng)建或者銷(xiāo)毀事件,做一些特殊的處理或者記錄?;赗edis的Spring-Session利用Spring Event將該事件發(fā)布出來(lái),我們可以使用EventListener監(jiān)聽(tīng)做處理。

@Component
@Slf4j
public class AnnotationDrivenEventListener {

  @EventListener
  public void handleSessionCreated(SessionCreatedEvent sessionCreatedEvent) {
    String sessionId = sessionCreatedEvent.getSessionId();
    log.info("session id:{} created", sessionId);
  }

  @EventListener
  public void handleSessionDestroyed(SessionDestroyedEvent sessionDestroyedEvent) {
    String sessionId = sessionDestroyedEvent.getSessionId();
    log.info("session id:{} destroyed", sessionId);
  }
}

總結(jié)

Spring Session提供了非常便利的,基于關(guān)系型數(shù)據(jù)庫(kù)或者Redis的Session解決方案。

Redis版訪(fǎng)問(wèn)速度快,基于Redis的過(guò)期策略,保證過(guò)期數(shù)據(jù)會(huì)被刪除,同時(shí)支持事件訂閱。

數(shù)據(jù)庫(kù)版直接基于數(shù)據(jù)庫(kù),無(wú)需單獨(dú)引入其他存儲(chǔ)。但是訪(fǎng)問(wèn)速度相對(duì)較慢,過(guò)期數(shù)據(jù)需要依賴(lài)應(yīng)用程序自身進(jìn)行刪除。同時(shí)沒(méi)有提供事件訂閱能力。

以上就是Spring Session的使用示例的詳細(xì)內(nèi)容,更多關(guān)于Spring Session的使用的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • spring?boot項(xiàng)目自定義參數(shù)校驗(yàn)規(guī)則示例詳解

    spring?boot項(xiàng)目自定義參數(shù)校驗(yàn)規(guī)則示例詳解

    這篇文章主要介紹了spring boot項(xiàng)目如何自定義參數(shù)校驗(yàn)規(guī)則,自定義校驗(yàn)規(guī)則和自帶的規(guī)則實(shí)現(xiàn)方式一樣,先自定義一個(gè)注解,然后指定校驗(yàn)類(lèi),在校驗(yàn)類(lèi)里實(shí)現(xiàn)具體的校驗(yàn)規(guī)則,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • SpringSecurity+jwt+redis基于數(shù)據(jù)庫(kù)登錄認(rèn)證的實(shí)現(xiàn)

    SpringSecurity+jwt+redis基于數(shù)據(jù)庫(kù)登錄認(rèn)證的實(shí)現(xiàn)

    本文主要介紹了SpringSecurity+jwt+redis基于數(shù)據(jù)庫(kù)登錄認(rèn)證的實(shí)現(xiàn),其中也涉及到自定義的過(guò)濾器和處理器,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • Java基于jdbc連接mysql數(shù)據(jù)庫(kù)操作示例

    Java基于jdbc連接mysql數(shù)據(jù)庫(kù)操作示例

    這篇文章主要介紹了Java基于jdbc連接mysql數(shù)據(jù)庫(kù)操作,結(jié)合完整實(shí)例形式分析了java使用jdbc連接mysql數(shù)據(jù)庫(kù)的具體步驟與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-07-07
  • Java中常用的設(shè)計(jì)模式之策略模式詳解

    Java中常用的設(shè)計(jì)模式之策略模式詳解

    這篇文章主要為大家詳細(xì)介紹了Java中常用的設(shè)計(jì)模式之策略模式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-02-02
  • SpringBoot中restTemplate請(qǐng)求存在亂碼問(wèn)題的解決方法

    SpringBoot中restTemplate請(qǐng)求存在亂碼問(wèn)題的解決方法

    這篇文章主要介紹了SpringBoot中restTemplate請(qǐng)求存在亂碼問(wèn)題的解決方法,文中有相關(guān)的圖文和代碼示例供大家參考,對(duì)大家的解決問(wèn)題有一定的幫助,需要的朋友可以參考下
    2024-11-11
  • ReentrantLock源碼詳解--條件鎖

    ReentrantLock源碼詳解--條件鎖

    這篇文章主要介紹了ReentrantLock源碼之條件鎖,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,下面我們來(lái)一起學(xué)習(xí)一下吧
    2019-06-06
  • 深入了解JAVA 軟引用

    深入了解JAVA 軟引用

    這篇文章主要介紹了JAVA 軟引用的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-08-08
  • Java中的Kafka為什么性能這么快及4大核心詳析

    Java中的Kafka為什么性能這么快及4大核心詳析

    這篇文章主要介紹了Java中的Kafka為什么性能這么快及4大核心詳析,文章通過(guò)圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • mybatis 為什么千萬(wàn)不要使用 where 1=1

    mybatis 為什么千萬(wàn)不要使用 where 1=1

    這篇文章主要介紹了mybatis 為什么千萬(wàn)不要使用 where 1=1,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • java?串口工具jSerialComm示例詳解

    java?串口工具jSerialComm示例詳解

    這篇文章主要介紹了java?串口工具jSerialComm,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-06-06

最新評(píng)論

新邵县| 淳化县| 方正县| 阿合奇县| 开化县| 灵宝市| 金塔县| 汉中市| 夏邑县| 南康市| 疏勒县| 泽普县| 宾阳县| 长岭县| 建昌县| 巍山| 巴彦淖尔市| 陆良县| 商南县| 洛扎县| 清丰县| 聂拉木县| 隆德县| 开江县| 尚义县| 孟津县| 嵩明县| 敦化市| 清流县| 景东| 盱眙县| 余姚市| 厦门市| 平利县| 荣成市| 华池县| 故城县| 全椒县| 曲阳县| 二手房| 锡林浩特市|