由于HTTP协议是无状态的协议,一次浏览器和服务器的交互过程就是:
发送请求
浏览器----------------------------->服务器
返回请求
浏览器----------------------------->服务器
这就是一次会话,对话完成后这次会话就结束了,服务器端并不能记住这个人的信息状态,下次再次对话时,服务器不能确定此次会话主人的信息,所以服务器端要记录用户的状态时,就要用某种机制来识别到具体的用户,这个机制就是Session。
Session是服务器为每个用户创建一个会话,存储用户的相关信息,以便多次请求能够定位到同一个上下文。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 内的客户信息将会被识别统一上下文,整个用户会话中一直存在下去,会话场景则不会丢失。当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,服务器将终止该会话。
Web开发中,web-server可以自动为同一个浏览器的访问用户自动创建session,提供数据存储功能。最常见的,会把用户的登录信息、用户信息存储在session中,以保持登录状态。
这个时候则需要使用Cookie;
每次HTTP请求的时候,客户端都会发送相应的Cookie信息到服务端。
实际上大多数应用都是用Cookie来实现Session跟踪的,第一次创建Session时,服务端会在HTTP协议中向客户端Cookie中记录一个Session ID,以后每次请求把这个会话ID发送到服务器,这样服务端就会知道客户端是谁了;
如果客户端的浏览器禁用了Cookie,会使用一种叫URL重写的技术来进行session会话跟踪,即每次HTTP交互,URL后面都会被附加上一个诸如sessionId=xxx的参数,服务端据此来识别客户端是谁。
在Web项目中,Session会话管理时一个很重要的部分,用于存储与记录用户的状态或相关的数据信息;通常情况下Session交由容器(Tomcat)来负责存储和管理,但是如果项目部署到多台Tomcat中,Session管理则会存在很大的问题。如:多台Tomcat之间Session无法共享,运用负载均衡部署的话,用户会出现不确定的退出登录的状况;或一旦Tomcat关闭或重启也会导致session会话失效;因此如果项目部署在多台Tomcat中,就要解决Session共享的问题
Spring Session是Spring家族中的子成员,它提供一组api和实现,用于管理用户的session信息;它把servlet容器实现的httpSession替换为spring-session,专注于解决session管理问题,Session信息存储在Redis中,可简单快速且无缝的集成到我们的应用中;
Spring 网址https://spring.io/
Spring Session 的特性:
添加Spring Session的maven依赖:
<!-- spring session 依赖-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
<version>1.3.1.RELEASE</version>
</dependency>
<!-- spring session redis 依赖-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>1.3.1.RELEASE</version>
</dependency>
<!-- spring-dataa-redis 依赖的JAR配置-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.8.8.RELEASE</version>
</dependency>
<!-- jedis依赖的JAR配置-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<!-- spring web 依赖的JAR配置-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<!-- servlet依赖的JAR配置-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<!-- jsp依赖的JAR配置-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
</dependency>
2.在web.xml文件中配置springSessionRepositoryFilter过滤器
全局过滤器
springSessionRepositoryFilter
org.springframework.web.filter.DelegatingFilterProxy
springSessionRepositoryFilter
/*
3.在web.xml文件中加载spring配置文件
第一种 监听器启动spring容器(Java)
contextConfigLocation
classpath:applicationContext.xml
org.springframework.web.context.ContextLoaderListener
第二种 使用spring mvc的DispatcherServlet启动spring容器
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
4.Spring配置文件(applicationContext.xml)配置一个RedisHttpSessionConfiguration类(在session的配置文件中配置即可)
<!--
spring注解、bean的处理器
注解的配置 识别注解
-->
<context:annotation-config/>
<!-- Spring session的配置类 -->
<bean class:"org.springframework.session.data.redis.config.annotation.web.RedisHttpSessionConfiguration">
<!--指定session策略-->
<!--<property name="httpSessionStrategy" ref="httpSessionStrategy"/>-->
<!--
指定过期时间
单位 秒
-->
<property name="maxInactiveIntervalInSeconds" value="1800" />
</bean>
<bean id="httpSessionStrategy" class="org.springframework.session.web.http.CookieHttpSessionStrategy">
<!--httpsession策略-->
<property name="httpSessionStrategy" ref="httpSessionStrategy"/>
</bean>
<!-- 采用cookie策略 -->
<bean id="httpSessionStrategy" class="org.springframework.session.web.http.CookieHttpSessionStrategy">
<property name="cookieSerializer" ref="cookieSerializer" />
</bean>
<bean id="cookieSerializer" class="org.springframework.session.web.http.DefaultCookieSerializer" />
<!--指定cookie的域名及路径-->
<property name="cookiePath" value="/"/>
<property name="domainName" value="web.com"/>
</bean>
5.Spring配置文件配置Spring-data-redis
<!-- 配置jedis连接工厂,用于连接redis -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${redis.hostName}"/>
<property name="port" value="${redis.port}"/>
<property name="password" value="${redis.password}"/>
<!-- 是否使用连接池 -->
<property name="usePool" value="${redis.usePool}"/>
<!-- 超时时间 -->
<property name="timeout" value="${redis.timeout}"/>
</bean>
<!-- 读取redis.properties属性配置文件 -->
<context:property-placeholder location="classpath:redis.properties"/>
配置redis配置文件
redis.hostName=127.0.0.1
redis.port=6379
redis.password=123456
redis.usePool=true
redis.timeout=10000
springBoot配置
1.maven配置依赖
<!--redis 依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--sessions 依赖-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
2.配置redis.properties文件
在applications.properties文件中加上:
#同时引用redies.properties文件相当于mvc中<import resource="xxxxx.xml" />
spring.profiles.include=redis
spring.redis.host=localhost
spring.redis.port=6379
# spring session使用存储类型,spirngboot默认就是使用redis方式,如果不想用可以填none。
spring.session.store-type=redis
#连接超时时间(毫秒)
spring.redis.timeout=1800000
#指定cookie的路径
server.servlet.session.cookie.path="/"
#指定cookie的域名
server.servlet.session.cookie.domain="web.com"
3.在启动类中加入@EnableRedisHttpSession 注解
4.在需要操作Redis的类中注入redisTemplate,它是由spring自动配置好的
@Autowride
private RedisTemplate<String,String> redisTemplate;
//写代码时最好将key的序列化设置成可读性比较强的
redisTemplate.setKeySerializer(new StringSerializer());
或者
@Autowride
private RedisTemplate<Object,Object> redisTemplate;
泛型里只能写
同域名下相同项目实现session共享
在同一个域名下,比如:www.myweb.com,同一个项目部署了多台tomcat,此为典型的集群方式
同域名下不同项目实现session共享
在同一个域名下有多个不同的项目,如:www.web,com/jiekuan;www.web.com/touzi;
注意:设置Cookie路径为根/上下文
在applicationContext.xml文件的RedisHttpSessionConfiguration类的bean中设置session策略
<!-- Spring session的配置类 -->
<bean class:"org.springframework.session.data.redis.config.annotation.web.RedisHttpSessionConfiguration">
<!--指定session策略-->
<!--<property name="httpSessionStrategy" ref="httpSessionStrategy"/>-->
<!--
指定过期时间
单位 秒
-->
<property name="maxInactiveIntervalInSeconds" value="1800" />
</bean>
<bean id="httpSessionStrategy" class="org.springframework.session.web.http.CookieHttpSessionStrategy">
<!--httpsession策略-->
<property name="httpSessionStrategy" ref="httpSessionStrategy"/>
</bean>
<!-- 采用cookie策略 -->
<bean id="httpSessionStrategy" class="org.springframework.session.web.http.CookieHttpSessionStrategy">
<!-- cookie的存放方式 -->
<property name="cookieSerializer" ref="cookieSerializer" />
</bean>
<bean id="cookieSerializer" class="org.springframework.session.web.http.DefaultCookieSerializer" />
<!-- 不设置的时候默认的是项目工程下的 -->
<!--指定cookie的路径 存放在根路径下-->
<property name="cookiePath" value="/"/>
</bean>
同域名不同二级子域名下的项目实现session共享
同一个根域名但是二级域名不同,如:www.web.com、beijing.web.com、nanjing.web.com
* 设置Cookie路径为根/上下文
同上
* 设置cookie域名根域名web.com
<bean id="cookieSerializer" class="org.springframework.session.web.http.DefaultCookieSerializer" />
<!--指定cookie的路径-->
<property name="cookiePath" value="/"/>
<!--指定cookie的域名-->
<property name="domainName" value="web.com"/>
</bean>
不同根域名下的项目实现session共享
根域名不同 如:www.baidu.com、www.webo.com,要实现一处登录,处处登录,Spring Session不支持,需要采用其它方式。
如:单点登录(Single Sign On,SSO),在多个应用系统中,用户只需要登录一次就可访问所有相互信任的应用系统。
比如阿里的多个业务线之间的登录模式