任何一种技术的出现,都是来解决特定的问题的!
本篇开始学习Spring-Session相关的一些知识学习整理,让我们开始吧!
Spring-Session介绍
- Spring-Session使用的场景?
HttpSession是通过Servlet容器进行创建和管理的,在单机环境中。通过Http请求创建的Session信息是存储在Web服务器内存中,如Tomcat/Jetty。
假如当用户通过浏览器访问应用服务器,session信息中保存了用户的登录信息,并且session信息没有过期失,效那么用户就一直处于登录状态,可以做一些登录状态的业务操作!
但是现在很多的服务器都采用分布式集群的方式进行部署,一个Web应用,可能部署在几台不同的服务器上,通过LVS或者Nginx等进行负载均衡(一般使用Nginx+Tomcat实现负载均衡)。此时来自同一用户的Http请求将有可能被分发到不同的web站点中去(如:第一次分配到A站点,第二次可能分配到B站点)。那么问题就来了,如何保证不同的web站点能够共享同一份session数据呢?
假如用户在发起第一次请求时候访问了A站点,并在A站点的session中保存了登录信息,当用户第二次发起请求,通过负载均衡请求分配到B站点了,那么此时B站点能否获取用户保存的登录的信息呢?答案是不能的,因为上面说明,Session是存储在对应Web服务器的内存的,不能进行共享,此时Spring-session就出现了,来帮我们解决这个session共享的问题!
- 如何进行Session共享呢?
简单点说就是请求http请求经过Filter职责链,根据配置信息过滤器将创建session的权利由tomcat交给了Spring-session中的SessionRepository,通过Spring-session创建会话,并保存到对应的地方。
实际上实现Session共享的方案很多,其中一种常用的就是使用Tomcat、Jetty等服务器提供的Session共享功能,将Session的内容统一存储在一个数据库(如MySQL)或缓存(如Redis,Mongo)中,
而上面说的使用Nginx也可以,使用iphash策略。 【Nginx】实现负载均衡的几种方式 在使用Nginx的iphash策略时候,每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,也可以解决session的问题。
- Spring官方介绍
- Why Spring Session & HttpSession?
Spring会话提供了与HttpSession的透明集成,允许以应用程序容器(即Tomcat)中性的方式替换HttpSession,但是我们从中得到了什么好处呢?
- 集群会话——Spring会话使支持集群会话变得微不足道,而不需要绑定到应用程序容器的特定解决方案。
- 多个浏览器会话——Spring会话支持在单个浏览器实例中管理多个用户会话(也就是多个经过验证的帐户,类似于谷歌)。
- RESTful api——Spring会话允许在header中提供会话id以使用RESTful api。
- Spring Session & WebSockets的完美集成。
项目搭建
整个项目的整体骨架:
基于XML配置方式的Spring Session
本次只讲解xml配置方式,javaConfig配置可以参考官方文档:Spring Java Configuration
环境说明
本次项目需要用户Nginx和Redis,如果没有配置Nginx的请看这里: Windows上Nginx的安装教程详解
没有配置Redis的请看这里:Redis——windows环境安装Redis和Redis sentinel部署教程
配置好了上面的环境,后下面开始正式的Spring-session搭建过程了!
1.添加项目依赖
首先新建一个Maven的Web项目,新建好之后在pom文件中添加下面的依赖:
<?xml version="1.0" encoding="UTF-8"?>4.0.0org.spring learn-spring-session 1.0-SNAPSHOTwarFirst Learn Spring Session1.74.3.4.RELEASE1.3.1.RELEASEjavax.servlet javax.servlet-api 3.0.1providedorg.springframework.session spring-session-data-redis ${spring-session.version}pombiz.paluch.redis lettuce 3.5.0.Finalorg.springframework spring-web ${spring.version}
2.web.xml配置
<?xml version="1.0" encoding="UTF-8"?>contextConfigLocationclasspath*:spring/*xmlorg.springframework.web.context.ContextLoaderListenerspringSessionRepositoryFilterorg.springframework.web.filter.DelegatingFilterProxyspringSessionRepositoryFilter/*REQUESTERRORindex.jsp
3.Xml的配置
在resources 下面新建一个xml,名词为 application-session.xml
<?xml version="1.0" encoding="UTF-8"?>
4.测试代码
新建 LoginServlet.java
@WebServlet("/login")public class LoginServlet extends HttpServlet { @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; request.getSession().setAttribute("testKey