一、项目结构
分布式 Session 主要配置文件为 spring-session.xml 和 web.xml,其他的配置为标准的 Web 工程的配置:
二、实现分布式 Session
2.1 基本依赖
<!--分布式 session 相关依赖-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
2.2 Session 拦截器
在 web.xml 中配置 Session 拦截器:
<!--配置http session-->
<filter>
<filter-name>springSessionRepositoryFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSessionRepositoryFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.3 实现原理
Spring 通过将 Session 信息存储到公共容器中,这样不同的 Web 服务就能共享到相同的 Session 信息,从而实现分布式 Session。Spring 支持使用 Redis, JDBC,MongoDB,Hazelcast 等作为公共的存储容器。这里我们以 Redis 作为公共的存储容器,需要创建配置文件 spring- session.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<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" xmlns:p="http://www.springframework.org/schema/p"
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-4.1.xsd">
<context:property-placeholder location="classpath:redis.properties"/>
<!--配置 http session-->
<bean id="redisHttpSessionConfiguration"
class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
<!--session 有效期 单位秒 每次访问都会刷新有效期-->
<property name="maxInactiveIntervalInSeconds" value="1800"/>
</bean>
<!--单机版本配置 redis 配置-->
<bean id="redisStandaloneConfiguration"
class="org.springframework.data.redis.connection.RedisStandaloneConfiguration">
<constructor-arg name="hostName" value="${redis.host}"/>
<constructor-arg name="port" value="${redis.port}"/>
</bean>
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:usePool="true">
<!--单机版本配置-->
<constructor-arg name="standaloneConfig" ref="redisStandaloneConfiguration"/>
<!--集群配置-->
<!--<constructor-arg name="clusterConfig" ref="redisClusterConfiguration"/>-->
</bean>
<!--集群配置-->
<!--<bean id="redisClusterConfiguration" class="org.springframework.data.redis.connection.RedisClusterConfiguration">
<property name="maxRedirects" value="3"/>
<constructor-arg>
<set>
<value>127.0.0.1:6379</value>
<value>127.0.0.1:6380</value>
<value>127.0.0.1:6381</value>
</set>
</constructor-arg>
</bean>-->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
p:connection-factory-ref="jedisConnectionFactory"/>
</beans>
三、验证分布式 Session
3.1 测试准备
创建测试接口和测试页面:
@Controller
public class LoginController {
@RequestMapping
public String index(){
return "index";
}
@RequestMapping("home")
public String home(){
return "home";
}
@PostMapping("login")
public String login(User user, HttpSession session, HttpServletRequest request, Model model){
// 随机生成用户 id
user.setUserId(Math.round(Math.floor(Math.random() *10*1000)));
// 将用户信息保存到 id 中
session.setAttribute("USER",user);
return "redirect:home";
}
}
登录页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录页面</title>
</head>
<body>
<h5>服务器:<%=request.getServerName()+":"+request.getServerPort()%></h5>
<form action="${pageContext.request.contextPath}/login" method="post">
用户:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
<button type="submit">登录</button>
</form>
</body>
</html>
session 信息展示页面 (home.jsp):
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>主页面</title>
</head>
<body>
<h5>服务器:<%=request.getServerName()+":"+request.getServerPort()%></h5>
<h5>登录用户: ${sessionScope.USER.username} </h5>
<h5>用户编号: ${sessionScope.USER.userId} </h5>
</body>
</html>
3.2 测试结果
这里采用两个 Tomcat 分别启动项目,在第一个项目的 index.jsp 页面进行登录;第二个项目不登录,直接访问 Session 展示页home.jsp :
Tomcat 1 配置:
Tomcat 2 配置:
测试结果: