首先是Spring Session的官方文档地址 : http://docs.spring.io/spring-session/docs/1.0.1.RELEASE/reference/html5/
里面可以看到介绍:
- HttpSession: 集群会话、浏览器多会话支持、rest样式api
- WebSocket
1.搭建Maven工程
官方示例使用Maven工程实现,需要先搭建Maven工程并转为web项目。具体步骤见另外一篇博客(我也是按照他的来实现的,就不粘过来了,尊重原创) http://b-l-east.iteye.com/blog/1246482
按照步骤创建工程TestHttpSession,最后部署至tomcat并启动,访问 http://localhost:8080/TestHttpSession,说明项目搭建成功。
修改/创建src/main/webapp/index.jsp,代码如下
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html lang="en"> <head> <title>Session Attributes</title> <link rel="stylesheet" href="assets/bootstrap.min.css"> <style type="text/css"> body { padding: 1em; } </style> </head> <body> <div class="container"> <h1>Description</h1> <p>This application demonstrates how to use a Redis instance to back your session. Notice that there is no JSESSIONID cookie. We are also able to customize the way of identifying what the requested session id is.</p> <h1>Try it</h1> <form class="form-inline" role="form" action="./session" method="post"> <label for="attributeValue">Attribute Name</label> <input id="attributeValue" type="text" name="attributeName"/> <label for="attributeValue">Attribute Value</label> <input id="attributeValue" type="text" name="attributeValue"/> <input type="submit" value="Set Attribute"/> </form> <hr/> <table class="table table-striped"> <thead> <tr> <th>Attribute Name</th> <th>Attribute Value</th> </tr> </thead> <tbody> <c:forEach items="${sessionScope}" var="attr"> <tr> <td><c:out value="${attr.key}"/></td> <td><c:out value="${attr.value}"/></td> </tr> </c:forEach> </tbody> </table> </div> </body> </html>
访问 http://localhost:8080/TestHttpSession,可看到首页。
设置attributeName和attributeValue并提交后,可以在下方看到设置的值。
如在页面中加入<%=session.getClass() %>以输出session的类型,可以看到session为:class org.apache.catalina.session.StandardSessionFacade类。
2.加入依赖库
修改pom.xml, <dependencies> </dependencies>标签内最后加入以下代码段
<dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> <version>1.0.1.RELEASE</version> <type>pom</type> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.1.6.RELEASE</version> </dependency>
保存后项目会自动下载spring及spring session,jedis等依赖库。
3.加入配置代码
按照官方文档,在src/main/java源文件夹下创建sample包,并创建Config类
,代码如下
package sample; import org.springframework.context.annotation.Bean; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; import org.springframework.session.redis.embedded.EnableEmbeddedRedis; import org.springframework.session.redis.embedded.RedisServerPort; // tag::class[] @EnableEmbeddedRedis // <1> @EnableRedisHttpSession // <2> public class Config { @Bean public JedisConnectionFactory connectionFactory(@RedisServerPort int port) { JedisConnectionFactory connection = new JedisConnectionFactory(); // <3> connection.setPort(port); return connection; } }
这本是从GitHub上下载的源码,但是类中会报错,暂时忽略该问题,继续按官方文档执行。
在sample包下新建Initializer类,代码如下
package sample; import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer; // tag::class[] public class Initializer extends AbstractHttpSessionApplicationInitializer { // <1> public Initializer() { super(Config.class); // <2> } } // end::class[]
该类的作用是在应用启动时加载Config类,执行Config中的启动redis并创建连接等操作。
在sample包下新建SessionServlet类,代码如下
package sample; import javax.servlet.*; import javax.servlet.annotation.*; import javax.servlet.http.*; import java.io.IOException; // tag::class[] @WebServlet("/session") public class SessionServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String attributeName = req.getParameter("attributeName"); String attributeValue = req.getParameter("attributeValue"); req.getSession().setAttribute(attributeName, attributeValue); resp.sendRedirect(req.getContextPath() + "/"); } private static final long serialVersionUID = 2878267318695777395L; } // tag::end[]
该类的作用是实现路径为/session的servlet,可以将属性post至session中保存。
4.部署测试
重新发布至tomcat。
访问 http://localhost:8080/TestHttpSession,发现无法访问。
查看tomcat控制台,发现意料之中的错误。因Config类中的类引用找不到,系统启动失败。
因Config类中对EnableEmbeddedRedis、RedisServerPort、RedisServerPort 这三个类的引用根本找不到导致类编译失败。
Config类的作用是EnableEmbeddedRedis自动创建内建的redis缓存,并使用jedis连接缓存、创建连接工厂,以供会话存储查询使用。但是不知道是不是因为源码版本的问题,根本找不到这几个类,所以无法启动缓存,jedis也无法连接。
所以只要使用外部redis缓存服务器,并将spring-jedis配置连接至外部缓存,就可以解决该问题。
5.使用外部缓存
redis官网地址: http://redis.io/
本想安装windows版,结果发现redis官方不支持windows。虽然github上有其他版本支持windows的redis,但是安装后启动不成功,遂放弃转向Linux服务器版本。
参考文章如下:
Redis介绍以及安装(Linux): http://www.cnblogs.com/silent2012/p/3499654.html
Redis常用命令: http://www.linuxidc.com/Linux/2012-03/57573.htm
按照文档将redis安装在linux服务器192.168.24.31上并启动redis-server,端口默认6379。
修改sample包下Config类,代码如下:
package sample; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; // tag::class[] @Configuration @EnableRedisHttpSession // <2> public class Config { @Bean public JedisConnectionFactory connectionFactory() { JedisConnectionFactory connection = new JedisConnectionFactory(); // <3> connection.setPort(6379); connection.setHostName("192.168.24.31"); return connection; } } // end::class[]
修改将内建redis的引用、启动去掉,并连接至刚配好的外部redis:192.168.24.31:6379。
5.部署测试
重新发布至tomcat。
访问 http://localhost:8080/TestHttpSession,可看到首页。
设置attributeName和attributeValue并提交后,可以在下方看到设置的值。
同时可以看到session的类型变成了class org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper$HttpSessionWrapper类。
在linux服务器上使用redis-cli客户端的keys * 命令可看到会话已被缓存。
6.停机测试
将tomcat服务器关闭(但不关闭浏览器,以保留客户端cookie)。
重新启动tomcat后刷新页面,发现还可以取到之前session的值,说明集群会话缓存成功。
使用chrome开发者工具可看到cookie中原有的JSESSIONID被替换成了SESSION。