<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.yl</groupId>
<artifactId>redis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>redis</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
# redis的配置
# 密码
spring.redis.password=root123
# 主机,我这里连的是虚拟机上跑着的redis服务器
spring.redis.host=192.168.244.132
# 端口
spring.redis.port=6379
# 超时时间
spring.redis.timeout=25000
package com.yl.redis.domain;
import java.io.Serializable;
public class Student implements Serializable {
private String name;
private String sno;
private Integer grade;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSno() {
return sno;
}
public void setSno(String sno) {
this.sno = sno;
}
public Integer getGrade() {
return grade;
}
public void setGrade(Integer grade) {
this.grade = grade;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", sno='" + sno + '\'' +
", grade=" + grade +
'}';
}
}
package com.yl.redis;
import com.yl.redis.domain.Student;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
@SpringBootTest
class RedisApplicationTests {
@Autowired
RedisTemplate redisTemplate;
@Autowired
StringRedisTemplate stringRedisTemplate;
@Test
void contextLoads() {
Student student = new Student();
student.setSno("2020001");
student.setName("小明");
student.setGrade(98);
ValueOperations ops = redisTemplate.opsForValue();
ops.set("s1",student);
System.out.println(ops.get("s1"));
}
@Test
void test1() {
ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
ops.set("k1","hellovue");
System.out.println(ops.get("k1"));
}
}
1.对于单体应用而言,session共享是没必要的,但是对于分布式应用其存在是必要的
2.图解
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.yl</groupId>
<artifactId>sessionshare</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sessionshare</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<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-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
# redis的配置
#主机
spring.redis.host=192.168.244.132
# 端口号
spring.redis.port=6379
# 密码
spring.redis.password=root123
#超时时间
spring.redis.timeout=6000
package com.yl.sessionshare;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession;
@RestController
public class TestController {
@Value("${server.port}")
Integer port;
@GetMapping("/set")
public String setAttr(HttpSession session) {
session.setAttribute("name","小明");
return String.valueOf(port) + "setAttribute Successfully";
}
@GetMapping("/get")
public String getAttr(HttpSession session) {
String name = (String)session.getAttribute("name");
return name + ":" + port;
}
}
1.启动一个8080
2.启动一个8081
package com.yl.sessionshare;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession;
@RestController
public class TestController {
@Value("${server.port}")
Integer port;
@GetMapping("/set")
public String setAttr(HttpSession session) {
session.setAttribute("name","小明");
return String.valueOf(port) + "setAttribute Successfully";
}
@GetMapping("/get")
public String getAttr(HttpSession session) {
String name = (String)session.getAttribute("name");
return name + ":" + port;
}
}
1.访问8080端口的set和get方法
2.访问8081端口的get方法
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.yl</groupId>
<artifactId>sessionshare</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sessionshare</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<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-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
# redis的配置
#主机
spring.redis.host=192.168.244.135
# 端口号
spring.redis.port=6379
# 密码
spring.redis.password=root123
#超时时间
spring.redis.timeout=6000
package com.yl.sessionshare;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession;
@RestController
public class TestController {
@Value("${server.port}")
Integer port;
@GetMapping("/set")
public String setAttr(HttpSession session) {
session.setAttribute("name","小明");
return String.valueOf(port) + "setAttribute Successfully";
}
@GetMapping("/get")
public String getAttr(HttpSession session) {
String name = (String)session.getAttribute("name");
return name + ":" + port;
}
}
第一次:
第二次:
接口幂等性,简单来说就是同一个请求不断地发起,有时候我们需要这些请求的数据要保持一致性,也是只能发一次请求,不能让其发起多次重复的请求,结合redis来可以解决这种问题。
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.yl</groupId>
<artifactId>idempontent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>idempontent</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
# redis的配置
#主机
spring.redis.host=192.168.244.135
# 端口号
spring.redis.port=6379
# 密码
spring.redis.password=root123
#超时时间
spring.redis.timeout=6000
package com.yl.idempontent.token;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
@Service
public class RedisService {
@Autowired
private StringRedisTemplate redisTemplate;
public boolean setEx(String key,String value,Long expire) {
boolean flag = false;
try {
ValueOperations<String, String> ops = redisTemplate.opsForValue();
ops.set(key,value);
redisTemplate.expire(key,expire, TimeUnit.SECONDS);
flag = true;
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
public boolean exists(String key) {
return redisTemplate.hasKey(key);
}
public boolean remove(String key) {
if (exists(key)) {
return redisTemplate.delete(key);
}
return false;
}
}
package com.yl.idempontent.token;
import com.yl.idempontent.Exception.IdempontentException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.UUID;
@Service
public class TokenService {
@Autowired
RedisService redisService;
public String generateToken() {
String uuid = UUID.randomUUID().toString();
redisService.setEx(uuid,uuid,30000L);
return uuid;
}
public boolean verifyToken(HttpServletRequest request) throws IdempontentException {
String token = request.getHeader("token");
if (token == null || "".equals(token)) {
token = request.getParameter("token");
if (token == null || "".equals(token)) {
throw new IdempontentException("token 不存在");
}
}
if (!redisService.exists(token)) {
throw new IdempontentException("重复操作");
}
boolean b = redisService.remove(token);
if (!b) {
throw new IdempontentException("重复操作");
}
return true;
}
}
package com.yl.idempontent.Exception;
import com.yl.idempontent.interceptor.IdemPontentInterceptor;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalException {
@ExceptionHandler(IdempontentException.class)
public String idempontentException(IdempontentException e) {
return e.getMessage();
}
}
package com.yl.idempontent.Exception;
public class IdempontentException extends Exception {
public IdempontentException(String message) {
super(message);
}
}
package com.yl.idempontent.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoIdempotent {
}
package com.yl.idempontent.interceptor;
import com.yl.idempontent.Exception.IdempontentException;
import com.yl.idempontent.anno.AutoIdempotent;
import com.yl.idempontent.token.TokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
@Component
public class IdemPontentInterceptor implements HandlerInterceptor {
@Autowired
private TokenService tokenService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//对于没加到@AutoIdempotent注解的方法直接放行
if (!(handler instanceof HandlerMethod)) {
return true;
}
//对于加到@AutoIdempotent注解的方法进行拦截,校验token,只允许操作一次,不可重复操作
Method method = ((HandlerMethod) handler).getMethod();
AutoIdempotent annotation = method.getAnnotation(AutoIdempotent.class);
if (annotation != null) {
try {
return tokenService.verifyToken(request);
} catch (IdempontentException e) {
throw e;
}
}
return true;
}
}
package com.yl.idempontent.config;
import com.yl.idempontent.interceptor.IdemPontentInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMVCConfigure implements WebMvcConfigurer {
@Autowired
private IdemPontentInterceptor interceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(interceptor).addPathPatterns("/**");
}
}
package com.yl.idempontent.controller;
import com.yl.idempontent.anno.AutoIdempotent;
import com.yl.idempontent.token.TokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@Autowired
TokenService tokenService;
@GetMapping("/getToken")
public String getToken() {
return tokenService.generateToken();
}
@PostMapping("hello")
@AutoIdempotent
public String hello() {
return "hello java";
}
@PostMapping("hello2")
public String hello2() {
return "hello2 vue";
}
}
对hello接口进行了拦截,每调用一次hello接口,都要拿一次token才行
对hello2接口没有拦截,随便访问
package com.yl.idempontent.aop;
import com.yl.idempontent.Exception.IdempontentException;
import com.yl.idempontent.token.TokenService;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
@Component
@Aspect
public class IdempontentAspect {
@Autowired
TokenService tokenService;
@Pointcut("@annotation(com.yl.idempontent.anno.AutoIdempotent)")
public void pc1() {
}
@Before("pc1()")
public void before() throws IdempontentException {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
try {
tokenService.verifyToken(request);
} catch (IdempontentException e) {
throw e;
}
}
}
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.yl</groupId>
<artifactId>mongodb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mongodb</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
# mongodb端口号
spring.data.mongodb.port=27017
# 主机
spring.data.mongodb.host=192.168.244.135
spring.data.mongodb.username=admin
spring.data.mongodb.password=123456
# 新建一个数据库test用于保存数据
spring.data.mongodb.database=test
# 认证用户名和密码时使用admin数据库
spring.data.mongodb.authentication-database=admin
package com.yl.mongodb.model;
import java.io.Serializable;
public class User implements Serializable {
private Integer id;
private String userName;
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", userName='" + userName + '\'' +
", password='" + password + '\'' +
'}';
}
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_41359273/article/details/121051739
内容来源于网络,如有侵权,请联系作者删除!