使用Spring Session和JDBC DataStore进行会话管理

在Web应用程序中,用户会话管理对于管理用户状态至关重要。 在本文中,我们将学习在集群环境中管理用户会话所遵循的方法,以及如何使用Spring Session以更加简单和可扩展的方式实现它。

通常在生产环境中,我们将有多个服务器节点,并在它们前面有一个负载平衡器,并且所有客户端流量都将通过负载平衡器到达其中一个服务器节点。 因此,我们需要某种机制来使用户会话数据可用于集群环境中的每个客户端。
传统上,我们一直使用以下技术来管理会话:

  1. 单节点服务器
  2. 具有负载均衡器和粘性会话的多节点服务器
  3. 具有负载均衡器和会话复制的多节点服务器
  4. 持久性数据存储中具有负载均衡器和会话数据的多节点服务器

让我们简要地看一下这些方法。

1.单节点服务器

如果您的应用程序不是对企业至关重要的服务,那么并发用户不会太多,并且可以接受一些停机时间,那么我们可以进行单节点服务器部署,如下所示:


在此模型中,对于每个浏览器客户端,将在服务器上创建会话对象(对于Java,则为HttpSession ),并且SESSION_ID将被设置为浏览器上的cookie,以标识会话对象。 但是对于大多数应用程序来说,这种单服务器节点部署是不可接受的,因为如果服务器关闭,服务将完全关闭。

2.具有粘性会话的多节点服务器

为了使我们的应用程序高度可用并满足更多用户,我们可以在负载均衡器后面有多个服务器节点。 在“粘性会话”方法中,我们将负载均衡器配置为将所有请求从同一客户端路由到同一节点。

在此模型中,将在服务器节点中的任何一个上创建用户会话,并将来自该客户端的所有其他请求发送到该相同节点。 但是这种方法的问题是,如果服务器节点出现故障,那么该服务器上的所有用户会话都将消失。

3.具有会话复制的多节点服务器

在此模型中,用户会话数据将在所有服务器节点上复制,以便可以将任何请求路由到任何服务器节点。 即使一个节点发生故障,客户端请求也可以由另一节点服务。

但是会话复制需要更好的硬件支持,并涉及某些服务器特定的配置。

4.具有持久数据存储区中的会话数据的多节点服务器

在此模型中,用户会话数据将不保存在服务器的内存中,而是将其持久保存到数据存储中并将其与SESSION_ID关联。

此解决方案将独立于服务器,但是每当用户向其会话中添加一些信息时,我们可能都需要编写自定义代码以将会话数据透明地存储在Persistent数据存储区中。

这是Spring Session出现的地方。

Spring会议

Spring Session是方法4的实现,它是将会话数据存储在持久数据存储区中。 Spring Session支持RDBMS,Redis,HazelCast,MongoDB等多个数据存储,以透明地保存使用会话数据。 与往常一样,将Spring Session与Spring Boot一起使用就像添加依赖项和配置少量属性一样简单。
让我们看看如何在Spring Boot应用程序中将Spring Session与JDBC后端存储一起使用。

https://github.com/sivaprasadreddy/spring-session-samples

步骤1:创建Spring Boot应用程序

使用具有WebThymeleafJPAH2Session starters的最新版本(撰写时为2.0.0.RC1 )创建SpringBoot应用程序。
默认情况下,Session入门程序将添加org.springframework.session:spring-session-core依赖项 ,让我们在使用JDBC后端时将其更改为spring-session- jdbc

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

步骤2:配置Spring Session属性

我们可以在application.properties使用spring.session.store类型的属性配置Spring会议后端数据存储的类型。

spring.session.store-type=jdbc

当我们使用H2内存数据库时,Spring Session将创建以下表,这些表是通过脚本spring-session- jdbc -2.0.1.RELEASE.jar!/ org / springframework / session / jdbc / schema自动存储会话数据所需的。 -h2.sql

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),CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
);CREATE UNIQUE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (SESSION_ID);
CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (EXPIRY_TIME);
CREATE INDEX SPRING_SESSION_IX3 ON SPRING_SESSION (PRINCIPAL_NAME);CREATE TABLE SPRING_SESSION_ATTRIBUTES (SESSION_PRIMARY_ID CHAR(36) NOT NULL,ATTRIBUTE_NAME VARCHAR(200) NOT NULL,ATTRIBUTE_BYTES LONGVARBINARY NOT NULL,CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK 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
);CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_PRIMARY_ID);

但是,如果我们要使用其他RDBMS(例如MySQL),则可以进行如下配置:

添加MySQL Maven依赖项。

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

为MySQL配置数据源属性:

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/demo
spring.datasource.username=root
spring.datasource.password=admin

使用spring.session.jdbc.initialize-schema属性启用Spring Session表创建。

spring.session.jdbc.initialize-schema=always

有了这个属性,Spring Session将尝试使用脚本“ classpath:org / springframework / session / jdbc / schema-@@ platform @@。sql”创建表,因此在本例中,它将使用schema-mysql.sql

步骤3:将资料新增至HttpSession

现在,在src / main / resources / templates / index.html中创建一个简单的表单。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Spring Session + JDBC Demo</title>
</head>
<body><div><form th:action="@{/messages}" method="post"><textarea name="msg" cols="40" rows="4"></textarea><input type="submit" value="Save"/>
</form></div><div><h2>Messages</h2><ul th:each="m : ${messages}"><li th:text="${m}">msg</li></ul></div></body>
</html>

让我们实现一个Controller,以将消息添加到HttpSession并显示它们。

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;@Controller
public class MessagesController 
{@GetMapping("/")public String index(Model model, HttpSession session) {List<String> msgs = (List<String>) session.getAttribute("MY_MESSAGES");if(msgs == null) {msgs = new ArrayList<>();}model.addAttribute("messages", msgs);return "index";}@PostMapping("/messages")public String saveMessage(@RequestParam("msg") String msg, HttpServletRequest request) {List<String> msgs = (List<String>) request.getSession().getAttribute("MY_MESSAGES");if(msgs == null) {msgs = new ArrayList<>();request.getSession().setAttribute("MY_MESSAGES", msgs);}msgs.add(msg);return "redirect:/";}
}

现在,您可以启动应用程序并将一些消息添加到HttpSession中,并且可以看到SPRING_SESSIONSPRING_SESSION_ATTRIBUTES表中的行。 默认情况下,Spring Session将我们尝试添加到HttpSession的对象转换为ByteArray并将其存储在表中。

Spring SecuritySpring会议

由于SpringBoot的自动配置, Spring SessionSpring Security无缝集成。
让我们将Spring Security添加到我们的应用程序中。

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

application.properties中添加默认用户凭据,如下所示:

spring.security.user.name=admin
spring.security.user.password=secret

现在,如果您尝试访问http:// localhost:8080 /,您将被重定向到自动生成的登录页面。
登录并查看SPRING_SESSION表中的数据后,您可以看到登录用户名存储在PRINCIPAL_NAME列中。

Spring Session如何工作?

Spring Session提供了HttpServletRequestHttpSession的实现,分别是SessionRepositoryRequestWrapperHttpSessionWrapper 。 Spring Session提供SessionRepositoryFilter来拦截所有请求,并将HttpServletRequest包装在SessionRepositoryRequestWrapper中

SessionRepositoryRequestWrapper.getSession(boolean)中,它被重写以返回HttpSessionWrapper对象,而不是默认的HttpSession服务器实现。 HttpSessionWrapper使用SessionRepository将会话信息保存在数据存储中。

SessionRepository接口具有多种管理会话的方法。

public interface SessionRepository<S extends Session> 
{S createSession();void save(S session);S findById(String id);void deleteById(String id);
}

这个SessionRepository接口由各种类根据我们使用的后端类型实现。 在本例中,我们使用的是spring-session-jdbc提供的JdbcOperationsSessionRepository

结论

如您可能已经观察到的,由于Spring Boot的自动配置,我们可以通过使用Spring Session进行非常少的配置来有效地管理用户会话。 如果由于某种原因我们想将后端从JDBC更改为Redis或Hazelcast等,那只是简单的配置更改,因为我们不直接依赖于任何Spring Session类。

您可以在https://github.com/sivaprasadreddy/spring-session-samples中找到本文的源代码。

翻译自: https://www.javacodegeeks.com/2018/02/session-management-using-spring-session-jdbc-datastore.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/347762.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java面向对象(3)--类的成员方法

基本格式&#xff1a; 修饰符 返回值类型 方法名&#xff08;参数类型 形参1, 参数类型 形参2, …&#xff09;&#xff5b;方法体程序代码;return 返回值; &#xff5d;修饰符&#xff1a;public,缺省,private, protected等 返回值类型&#xff1a; ①没有返回值&#xff1a…

python统计图像直方图_计算机视觉7-像素点直方图统计、掩膜图像

1.灰度图的直方图(1)调用库import cv2import matplotlib.pyplot as pltimport numpy as np #创建掩膜时需要(2)绘图-方法1imgcv2.imread(F:cat.jpg,0)plt.hist(img.ravel(),256,[0,256])plt.show()plt.hist是一个画直方图的命令&#xff1b;img.ravel()可以将图片转化成一维数组…

计算机二级web题目(8.1)--综合选择题2

前些天发现了一个巨牛的人工智能学习电子书&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;无广告&#xff0c;忍不住分享一下给大家。&#xff08;点击跳转人工智能学习资料&#xff09; 1、一个栈的初始状态为空。现将元素1、2、3、4、5、A、B、C、D、E依次入栈,然后再…

Java面向对象(4)--封装和隐藏

Java中通过将数据声明为私有的(private)&#xff0c;再提供公共的&#xff08;public&#xff09;方法:获取getXxx()和设置setXxx()实现对该属性的操作&#xff0c;以实现下述目的&#xff1a; ①隐藏一个类中不需要对外提供的实现细节。 ②使用者只能通过事先定制好的方法来访…

跑来跑去:假人与AWS Lambda的第一次接触

一切始于埃及人在一个木框上滑动几块大理石以简单的算术使其大脑放松。 或许是希腊人发明了Antikythera机制来追踪行星的运动至每千年2度的精度 。 无论哪种方式&#xff0c;计算都已经走了很长一段路&#xff1a;查尔斯巴贝奇的分析引擎 &#xff0c;艾伦图灵的Enigma-breaker…

(2.1)HarmonyOS鸿蒙Ability创建,XML和Java页面布局UI

鸿蒙UI中&#xff0c;提供了两种编写布局的方式&#xff1a; ①在XML中声明UI布局 ②在Ability代码中直接通过Java创建布局 这两种方式创建出的布局没有本质差别&#xff0c;但是XML方式较为方便简单。 在XML文件中布局 与HTMLCSS的前端布局类似&#xff0c;通过使用不同类型的…

使用Azure Blob存储托管Maven工件

如果您使用Microsoft Azure并且将Java用于项目&#xff0c;则Azure Blob存储是托管团队工件的理想场所。 它很容易设置&#xff0c;而且很便宜。 如果您对它们的功能不特别感兴趣&#xff0c;那么它比设置现有存储库选项&#xff08;jfrog&#xff0c;nexus&#xff0c;archiv…

(2.2)HarmonyOS鸿蒙页面跳转

本文页面跳转基于《Ability创建子页面布局》所存在的两个页面MainAbility和SecondAbility。 在MainAbilitySlice中进行代码编写 package com.example.myapplication.slice;import com.example.myapplication.ResourceTable; import ohos.aafwk.ability.AbilitySlice; import o…

java 将换行代替_Java批量将文件中的段落替换成空格,根据指定分隔符换行(SQL示例)...

我的需求是SQL文件中有成千的类似数据&#xff0c;我要将它们进行转换格式&#xff0c;如下图第一步&#xff1a;将字符段楼替换&#xff0c;使用word排版把数据拷贝到word中&#xff0c;使用特殊字符替换点击全部替换&#xff0c;替换之后如下图&#xff0c;这时候它是一串很长…

计算机二级web题目(8.2)--基本操作题2

前些天发现了一个巨牛的人工智能学习电子书&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;无广告&#xff0c;忍不住分享一下给大家。&#xff08;点击跳转人工智能学习资料&#xff09; 1.在考生文件夹下的Web1目录中&#xff0c;存有1.htm文件&#xff0c;该文件不完…

java的选项板_CAD工具选项板的介绍以及新建方法

CAD中的工具选项板是【工具选项板】窗口中选项卡形式的区域&#xff0c;不但能提供组织、共享和放置块及填充图案的很有效的方法&#xff0c;还能够包含由第三方开发人员提供的自定义工具。【工具选项板】窗口包括注释、建筑、机械、电力、图案填充和土木工程等选项板。当需要向…

java单链表 提供增删改查_java实现单链表增删改查的实例代码详解

package 数据结构算法.链表;/**定义节点* 链表由节点构成*/public class node {private e e; //数据dataprivate node next; //指向下一个节点public node() {}public node(e e) {this.e e;}public node getnext() {return next;}public void setnext(node next) {this.next …

java接口安全怎么处理_Restful API 接口安全性设计

1.API接口设计规范2.安全性设计a.白名单限制仅接受特定系统的请求响应&#xff0c;调用方的IP地址需要在本系统中报备&#xff0c;否则无法调用b.合法身份合法性验证Basic Authentication :这种方式是直接将用户名和密码放到Header中&#xff0c;使用 Authorization: Basic Zm9…

使用Spring开发Java RESTful Web服务的7个理由

REST现在已成为开发Web服务的标准方法&#xff0c;涉及Java时&#xff0c;可以使用许多框架和库&#xff0c;例如JAX-RS&#xff0c;Restlet&#xff0c;Jersey&#xff0c;RESTEasy&#xff0c;Apache CFX等&#xff0c;但是我鼓励Java开发人员使用Spring框架来开发Java。开发…

java文件和xml文件_用Java分割大型XML文件

java文件和xml文件上周&#xff0c;我被要求用Java编写一些东西&#xff0c;该东西能够将一个30GB的XML文件拆分为可配置文件大小的较小部分。 文件的使用者将是一个中间件应用程序&#xff0c;该应用程序在XML的大尺寸方面存在问题。 在幕后&#xff0c;它使用某种DOM解析技术…

oracle java 并发_【转】JAVA并发教程(ORACLE官网资料)

本文是Oracle官方的Java并发相关的教程&#xff0c;感谢并发编程网的翻译和投递。计算机的使用者一直以为他们的计算机可以同时做很多事情。他们认为当其他的应用程序在下载文件&#xff0c;管理打印队列或者缓冲音频的时候他们可以继续在文字处理程序上工作。甚至对于单个应用…

部署Spring Boot Angular App(Maven和Tomcat)的4种方法

在上一篇有关Spring Boot angular 5的文章中 &#xff0c;我们使用Spring Boot angular 5实现了一个完整的堆栈端到端Web应用程序。在本文中&#xff0c;我们将讨论在tomcat上部署Spring Boot和Angle App的不同方法。 我们将创建一个具有后端&#xff08;服务器&#xff09;和前…

计算机二级web题目(8.3)--简单应用题2

前些天发现了一个巨牛的人工智能学习电子书&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;无广告&#xff0c;忍不住分享一下给大家。&#xff08;点击跳转人工智能学习资料&#xff09; 1.在考生文件夹下的Web3目录中&#xff0c;存有3.htm文件&#xff0c;该文件不完…

计算机二级web题目(8.4)--综合应用题2

前些天发现了一个巨牛的人工智能学习电子书&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;无广告&#xff0c;忍不住分享一下给大家。&#xff08;点击跳转人工智能学习资料&#xff09; 1.在考生文件夹下的Web5目录中&#xff0c;存有5.htm文件&#xff0c;该文件不完…

(3.5)HarmonyOS鸿蒙上下左右方向滑动

需要获取按下时候的坐标和松开时候的坐标&#xff0c;并将两者进行比较。 ①MainAbilitySlice.java文件 可以根据使用情况做修改代码中判断处的限制偏差范围。 package com.example.yeman.slice;import com.example.yeman.ResourceTable; import ohos.aafwk.ability.Ability…