2019-02-01 10:39:18 +08:00

199 lines
7.3 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>