HTTP协议本身是无状态,的为了保存会话信息,浏览器Cookie通过SessionID标识会话请求,服务器以SessionID为key来存储会话信息。 在 Web 项目开发中, Session 会话管理是一个很重要的部分, 用于存储与记录用户的状态或相关的数据。
使用框架的会话管理工具,也就是我们要介绍的 Spring session,这个方案既不依赖 tomcat 容器, 又不需要改动代码, 由 Spring session 框架为我们提供, 可以说是目前非常完美的 session 共享解决方案。Spring Session 是 Spring 家族中的一个子项目, 它提供一组 API 和实现, 用于管理用户的 session 信息.它把 servlet 容器实现的 httpSession 替换为 spring-session, 专注于解决 session 管理问题, Session 信息存储在 Redis 中, 可简单快速且无缝的集成到我们的应用中;
Spring Session 的特性:
(1)创建一个Maven的web module,名字为01-springsession-web
(2)完善Maven项目的结构
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.1.0version>
dependency>
<dependency>
<groupId>org.springframework.sessiongroupId>
<artifactId>spring-session-data-redisartifactId>
<version>1.3.1.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>5.2.10.RELEASEversion>
dependency>
(1) 创建向 session 放数据的 servlet
package session.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(urlPatterns = "/setSession")
public class SetSessionServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getSession().setAttribute("url","http://www.baidu.com");
resp.getWriter().write("OK");
}
}
(2) 创建从 session 中获取数据的 servlet
package session.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(urlPatterns = "/getSession")
public class GetSessionServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String url= (String) req.getSession().getAttribute("url");
resp.getWriter().write(url==null?"NO Session":url);
}
}
(3)部署访问测试(目前无法实现 session 共享)
可以在9100端口的服务器上访问/setSession,再在9200端口的服务器上访问 /getSession
这个时候我们通过测试会发现两个Tomcat服务器之间是无法共享session数据的
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="classpath:springsession.xml"/>
beans>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<bean id="redisHttpSessionConfiguration" class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
<property name="maxInactiveIntervalInSeconds" value="1800"/>
bean>
<bean id="jedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="127.0.0.1"/>
<property name="port" value="6379"/>
<property name="password" value="123456" />
bean>
beans>
这次通过上面已经介绍过的测试方法,我们可以发现session数据可以在端口号分别为9100和9200的两个不同的Tomcat服务器上实现共享了
<bean id="redisHttpSessionConfiguration" class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
<property name="maxInactiveIntervalInSeconds" value="1800"/>
<property name="cookieSerializer" ref="defaultCookieSerializer"/>
bean>
<bean id="defaultCookieSerializer" class="org.springframework.session.web.http.DefaultCookieSerializer">
<property name="cookiePath" value="/" />
bean>
同一个根域名,不同的二级子域名,比如北京和武汉的58同城域名:
添加域名映射: 找到C:\Windows\System32\drivers\etc路径下的hosts文件,在文件末尾加上:
127.0.0.1 p2p.myweb.com
127.0.0.1 shop.myweb.com
<bean id="defaultCookieSerializer" class="org.springframework.session.web.http.DefaultCookieSerializer">
<property name="cookiePath" value="/" />
<property name="domainName" value="myweb.com"/>
bean>