2019-07-31 17:39:13 +08:00

201 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# spring session 实现分布式 session
## 目录<br/>
<a href="#一项目结构">一、项目结构</a><br/>
<a href="#二分布式session的配置">二、分布式session的配置</a><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#21-引入依赖">2.1 引入依赖</a><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#22-在webxml中配置session拦截器">2.2 在web.xml中配置session拦截器</a><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#23-创建配置文件spring--sessionxml配置redis连接">2.3 创建配置文件spring- session.xml配置redis连接</a><br/>
<a href="#三验证分布式session">三、验证分布式session</a><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#31-创建测试controller和测试页面">3.1 创建测试controller和测试页面</a><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#32-启动项目">3.2 启动项目</a><br/>
## 正文<br/>
## 一、项目结构
分布式 session 主要配置文件为 spring-session.xml 和 web.xml其他的配置为标准的 web 工程的配置。
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-session.png"/> </div>
## 二、分布式session的配置
#### 2.1 引入依赖
```xml
<!--分布式 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 在web.xml中配置session拦截器
```xml
<!--配置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.xml配置redis连接
有两点需要特别说明:
1. spring-session 不仅提供了 redis 作为公共 session 存储的方案,同时也支持 jdbc、mongodb、Hazelcast 等作为公共 session 的存储;
2. 对于 redis 存储方案而言,官方也提供了不止一种整合方式,这里我们选取的整合方案是 jedis 客户端作为连接,当然也可以使用 Lettuce 作为客户端连接。
```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和测试页面
```java
@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";
}
}
```
登录页面:
```jsp
<%@ 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)
```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 配置:
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-session-tomcat01.png"/> </div>
tomcat 2 配置:
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-session-tomcat02.png"/> </div>
**测试结果:**
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-session-8080.png"/> </div>
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-session-8090.png"/> </div>