Browse Source

spring-boot-demo-session 完成

pull/1/head
Yangkai.Shen 5 years ago
parent
commit
66776f87a5
13 changed files with 482 additions and 0 deletions
  1. +1
    -0
      pom.xml
  2. +25
    -0
      spring-boot-demo-session/.gitignore
  3. +126
    -0
      spring-boot-demo-session/README.md
  4. +73
    -0
      spring-boot-demo-session/pom.xml
  5. +27
    -0
      spring-boot-demo-session/src/main/java/com/xkcoding/session/SpringBootDemoSessionApplication.java
  6. +39
    -0
      spring-boot-demo-session/src/main/java/com/xkcoding/session/config/WebMvcConfig.java
  7. +21
    -0
      spring-boot-demo-session/src/main/java/com/xkcoding/session/constants/Consts.java
  8. +67
    -0
      spring-boot-demo-session/src/main/java/com/xkcoding/session/controller/PageController.java
  9. +37
    -0
      spring-boot-demo-session/src/main/java/com/xkcoding/session/interceptor/SessionInterceptor.java
  10. +27
    -0
      spring-boot-demo-session/src/main/resources/application.yml
  11. +10
    -0
      spring-boot-demo-session/src/main/resources/templates/index.html
  12. +12
    -0
      spring-boot-demo-session/src/main/resources/templates/login.html
  13. +17
    -0
      spring-boot-demo-session/src/test/java/com/xkcoding/session/SpringBootDemoSessionApplicationTests.java

+ 1
- 0
pom.xml View File

@@ -35,6 +35,7 @@
<module>spring-boot-demo-swagger</module>
<module>spring-boot-demo-swagger-beauty</module>
<module>spring-boot-demo-rbac-security</module>
<module>spring-boot-demo-session</module>
<module>spring-boot-demo-websocket</module>
<module>spring-boot-demo-websocket-socketio</module>
<module>spring-boot-demo-war</module>


+ 25
- 0
spring-boot-demo-session/.gitignore View File

@@ -0,0 +1,25 @@
/target/
!.mvn/wrapper/maven-wrapper.jar

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

### NetBeans ###
/nbproject/private/
/build/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

+ 126
- 0
spring-boot-demo-session/README.md View File

@@ -0,0 +1,126 @@
# spring-boot-demo-session

> 此 demo 主要演示了 Spring Boot 如何通过 Spring Session 实现Session共享、重启程序Session不失效。

## pom.xml

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<artifactId>spring-boot-demo-session</artifactId>
<version>1.0.0-SNAPSHOT</version>

<name>spring-boot-demo-session</name>
<description>Demo project for Spring Boot</description>

<parent>
<groupId>com.xkcoding</groupId>
<artifactId>spring-boot-demo</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- 对象池,使用redis时必须引入 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
</dependencies>

<build>
<finalName>spring-boot-demo-session</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>
```

## application.yml

```yaml
server:
port: 8080
servlet:
context-path: /demo
spring:
session:
store-type: redis
redis:
flush-mode: immediate
namespace: "spring:session"
redis:
host: localhost
port: 6379
# 连接超时时间(记得添加单位,Duration)
timeout: 10000ms
# Redis默认情况下有16个分片,这里配置具体使用的分片
# database: 0
lettuce:
pool:
# 连接池最大连接数(使用负值表示没有限制) 默认 8
max-active: 8
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
max-wait: -1ms
# 连接池中的最大空闲连接 默认 8
max-idle: 8
# 连接池中的最小空闲连接 默认 0
min-idle: 0
```

## 测试

> 测试 重启程序,Session 不失效的场景

1. 打开浏览器,访问首页:http://localhost:8080/demo/page/index
2. 最开始未登录,所以会跳转到登录页:http://localhost:8080/demo/page/login?redirect=true 然后点击登录按钮
3. 登录之后,跳转回首页,此时可以看到首页显示token信息。
4. 重启程序。不关闭浏览器,直接刷新首页,此时不跳转到登录页。测试成功!

## 参考

- Spring Session 官方文档:https://docs.spring.io/spring-session/docs/current/reference/html5/guides/boot-redis.html#updating-dependencies

+ 73
- 0
spring-boot-demo-session/pom.xml View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<artifactId>spring-boot-demo-session</artifactId>
<version>1.0.0-SNAPSHOT</version>

<name>spring-boot-demo-session</name>
<description>Demo project for Spring Boot</description>

<parent>
<groupId>com.xkcoding</groupId>
<artifactId>spring-boot-demo</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- 对象池,使用redis时必须引入 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
</dependencies>

<build>
<finalName>spring-boot-demo-session</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

+ 27
- 0
spring-boot-demo-session/src/main/java/com/xkcoding/session/SpringBootDemoSessionApplication.java View File

@@ -0,0 +1,27 @@
package com.xkcoding.session;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
* <p>
* 启动类
* </p>
*
* @package: com.xkcoding.session
* @description: 启动类
* @author: yangkai.shen
* @date: Created in 2018-12-19 19:35
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
@SpringBootApplication
public class SpringBootDemoSessionApplication {

public static void main(String[] args) {
SpringApplication.run(SpringBootDemoSessionApplication.class, args);
}

}


+ 39
- 0
spring-boot-demo-session/src/main/java/com/xkcoding/session/config/WebMvcConfig.java View File

@@ -0,0 +1,39 @@
package com.xkcoding.session.config;

import com.xkcoding.session.interceptor.SessionInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
* <p>
* WebMvc 配置类
* </p>
*
* @package: com.xkcoding.session.config
* @description: WebMvc 配置类
* @author: yangkai.shen
* @date: Created in 2018-12-19 19:50
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private SessionInterceptor sessionInterceptor;

@Override
public void addInterceptors(InterceptorRegistry registry) {
InterceptorRegistration sessionInterceptorRegistry = registry.addInterceptor(sessionInterceptor);
// 排除不需要拦截的路径
sessionInterceptorRegistry.excludePathPatterns("/page/login");
sessionInterceptorRegistry.excludePathPatterns("/page/doLogin");
sessionInterceptorRegistry.excludePathPatterns("/error");

// 需要拦截的路径
sessionInterceptorRegistry.addPathPatterns("/**");
}
}

+ 21
- 0
spring-boot-demo-session/src/main/java/com/xkcoding/session/constants/Consts.java View File

@@ -0,0 +1,21 @@
package com.xkcoding.session.constants;

/**
* <p>
* 常量池
* </p>
*
* @package: com.xkcoding.session.constants
* @description: 常量池
* @author: yangkai.shen
* @date: Created in 2018-12-19 19:42
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
public interface Consts {
/**
* session保存的key
*/
String SESSION_KEY = "key:session:token";
}

+ 67
- 0
spring-boot-demo-session/src/main/java/com/xkcoding/session/controller/PageController.java View File

@@ -0,0 +1,67 @@
package com.xkcoding.session.controller;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.xkcoding.session.constants.Consts;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
* <p>
* 页面跳转 Controller
* </p>
*
* @package: com.xkcoding.session.controller
* @description: 页面跳转 Controller
* @author: yangkai.shen
* @date: Created in 2018-12-19 19:57
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
@Controller
@RequestMapping("/page")
public class PageController {
/**
* 跳转到 首页
*
* @param request 请求
*/
@GetMapping("/index")
public ModelAndView index(HttpServletRequest request) {
ModelAndView mv = new ModelAndView();

String token = (String) request.getSession().getAttribute(Consts.SESSION_KEY);
mv.setViewName("index");
mv.addObject("token", token);
return mv;
}

/**
* 跳转到 登录页
*
* @param redirect 是否是跳转回来的
*/
@GetMapping("/login")
public ModelAndView login(Boolean redirect) {
ModelAndView mv = new ModelAndView();

if (ObjectUtil.isNotNull(redirect) && ObjectUtil.equal(true, redirect)) {
mv.addObject("message", "请先登录!");
}
mv.setViewName("login");
return mv;
}

@GetMapping("/doLogin")
public String doLogin(HttpSession session) {
session.setAttribute(Consts.SESSION_KEY, IdUtil.fastUUID());

return "redirect:/page/index";
}
}

+ 37
- 0
spring-boot-demo-session/src/main/java/com/xkcoding/session/interceptor/SessionInterceptor.java View File

@@ -0,0 +1,37 @@
package com.xkcoding.session.interceptor;

import com.xkcoding.session.constants.Consts;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
* <p>
* 校验Session的拦截器
* </p>
*
* @package: com.xkcoding.session.interceptor
* @description: 校验Session的拦截器
* @author: yangkai.shen
* @date: Created in 2018-12-19 19:40
* @copyright: Copyright (c) 2018
* @version: V1.0
* @modified: yangkai.shen
*/
@Component
public class SessionInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
if (session.getAttribute(Consts.SESSION_KEY) != null) {
return true;
}
// 跳转到登录页
String url = "/page/login?redirect=true";
response.sendRedirect(request.getContextPath() + url);
return false;
}
}

+ 27
- 0
spring-boot-demo-session/src/main/resources/application.yml View File

@@ -0,0 +1,27 @@
server:
port: 8080
servlet:
context-path: /demo
spring:
session:
store-type: redis
redis:
flush-mode: immediate
namespace: "spring:session"
redis:
host: localhost
port: 6379
# 连接超时时间(记得添加单位,Duration)
timeout: 10000ms
# Redis默认情况下有16个分片,这里配置具体使用的分片
# database: 0
lettuce:
pool:
# 连接池最大连接数(使用负值表示没有限制) 默认 8
max-active: 8
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
max-wait: -1ms
# 连接池中的最大空闲连接 默认 8
max-idle: 8
# 连接池中的最小空闲连接 默认 0
min-idle: 0

+ 10
- 0
spring-boot-demo-session/src/main/resources/templates/index.html View File

@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>spring-boot-demo-session</title>
</head>
<body>
token的值: <h1 th:text="${token}"></h1>
</body>
</html>

+ 12
- 0
spring-boot-demo-session/src/main/resources/templates/login.html View File

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>spring-boot-demo-session</title>
</head>
<body>
<h1 th:text="${message}" style="background-color: red"></h1>

<button><a th:href="@{'/page/doLogin'}">登录</a></button>
</body>
</html>

+ 17
- 0
spring-boot-demo-session/src/test/java/com/xkcoding/session/SpringBootDemoSessionApplicationTests.java View File

@@ -0,0 +1,17 @@
package com.xkcoding.session;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootDemoSessionApplicationTests {

@Test
public void contextLoads() {
}

}


Loading…
Cancel
Save