Skip to content

Commit

Permalink
m
Browse files Browse the repository at this point in the history
  • Loading branch information
lenve committed Nov 15, 2021
1 parent a9aeafa commit e4ae293
Show file tree
Hide file tree
Showing 23 changed files with 689 additions and 0 deletions.
53 changes: 53 additions & 0 deletions idempotent/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?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.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.javaboy</groupId>
<artifactId>idempotent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>idempotent</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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

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

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.javaboy.idempotent;

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

@SpringBootApplication
public class IdempotentApplication {

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

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.javaboy.idempotent.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* @author 江南一点雨
* @微信公众号 江南一点雨
* @网站 http://www.itboyhub.com
* @国际站 http://www.javaboy.org
* @微信 a_java_boy
* @GitHub https://github.com/lenve
* @Gitee https://gitee.com/lenve
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoIdempotent {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.javaboy.idempotent.config;

import org.javaboy.idempotent.interceptor.IdempotentInterceptor;
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;

/**
* @author 江南一点雨
* @微信公众号 江南一点雨
* @网站 http://www.itboyhub.com
* @国际站 http://www.javaboy.org
* @微信 a_java_boy
* @GitHub https://github.com/lenve
* @Gitee https://gitee.com/lenve
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
IdempotentInterceptor idempotentInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(idempotentInterceptor).addPathPatterns("/**");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.javaboy.idempotent.controller;

import org.javaboy.idempotent.annotation.AutoIdempotent;
import org.javaboy.idempotent.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;

/**
* @author 江南一点雨
* @微信公众号 江南一点雨
* @网站 http://www.itboyhub.com
* @国际站 http://www.javaboy.org
* @微信 a_java_boy
* @GitHub https://github.com/lenve
* @Gitee https://gitee.com/lenve
*/
@RestController
public class HelloController {
@Autowired
TokenService tokenService;

@GetMapping("/gettoken")
public String getToken() {
return tokenService.createToken();
}

@PostMapping("/hello")
@AutoIdempotent
public String hello() {
return "hello";
}

@PostMapping("/hello2")
public String hello2() {
return "hello2";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.javaboy.idempotent.exception;

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
* @author 江南一点雨
* @微信公众号 江南一点雨 springboot
* @网站 http://www.itboyhub.com
* @国际站 http://www.javaboy.org
* @微信 a_java_boy
* @GitHub https://github.com/lenve
* @Gitee https://gitee.com/lenve
*/
@RestControllerAdvice
public class GlobalException {

@ExceptionHandler(IdempotentException.class)
public String idempotentException(IdempotentException e) {
return e.getMessage();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.javaboy.idempotent.exception;

/**
* @author 江南一点雨
* @微信公众号 江南一点雨
* @网站 http://www.itboyhub.com
* @国际站 http://www.javaboy.org
* @微信 a_java_boy
* @GitHub https://github.com/lenve
* @Gitee https://gitee.com/lenve
*/
public class IdempotentException extends Exception {
public IdempotentException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package org.javaboy.idempotent.interceptor;

import org.javaboy.idempotent.annotation.AutoIdempotent;
import org.javaboy.idempotent.exception.IdempotentException;
import org.javaboy.idempotent.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 org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
* @author 江南一点雨
* @微信公众号 江南一点雨 spring5 springmvc
* @网站 http://www.itboyhub.com
* @国际站 http://www.javaboy.org
* @微信 a_java_boy
* @GitHub https://github.com/lenve
* @Gitee https://gitee.com/lenve
*
*
*/
@Component
public class IdempotentInterceptor implements HandlerInterceptor {
@Autowired
TokenService tokenService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!(handler instanceof HandlerMethod)) {
return true;
}
Method method = ((HandlerMethod) handler).getMethod();
AutoIdempotent autoIdempotent = method.getAnnotation(AutoIdempotent.class);
if (autoIdempotent != null) {
try {
return tokenService.checkToken(request);
} catch (IdempotentException e) {
throw e;
}
}
return true;
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.javaboy.idempotent.token;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
* @author 江南一点雨
* @微信公众号 江南一点雨
* @网站 http://www.itboyhub.com
* @国际站 http://www.javaboy.org
* @微信 a_java_boy
* @GitHub https://github.com/lenve
* @Gitee https://gitee.com/lenve
*/
@Component
public class RedisService {
@Autowired
RedisTemplate redisTemplate;

public boolean setEx(String key, Object value, Long expireTime) {
boolean result = false;
try {
ValueOperations ops = redisTemplate.opsForValue();
ops.set(key, value);
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}

public boolean exists(String key) {
return redisTemplate.hasKey(key);
}

public boolean remove(String key) {
if (exists(key)) {
return redisTemplate.delete(key);
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.javaboy.idempotent.token;

import org.javaboy.idempotent.exception.IdempotentException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.yaml.snakeyaml.events.Event;

import javax.servlet.http.HttpServletRequest;
import java.util.UUID;

/**
* @author 江南一点雨
* @微信公众号 江南一点雨 idempotent
* @网站 http://www.itboyhub.com
* @国际站 http://www.javaboy.org
* @微信 a_java_boy
* @GitHub https://github.com/lenve
* @Gitee https://gitee.com/lenve
*/
@Component
public class TokenService {
@Autowired
RedisService redisService;

public String createToken() {
String uuid = UUID.randomUUID().toString();
redisService.setEx(uuid, uuid, 10000L);
return uuid;
}

public boolean checkToken(HttpServletRequest req) throws IdempotentException {
String token = req.getHeader("token");
if (StringUtils.isEmpty(token)) {
token = req.getParameter("token");
if (StringUtils.isEmpty(token)) {
throw new IdempotentException("token 不存在");
}
}
if (!redisService.exists(token)) {
throw new IdempotentException("重复的操作");
}
boolean remove = redisService.remove(token);
if (!remove) {
throw new IdempotentException("重复的操作");
}
return true;
}
}
3 changes: 3 additions & 0 deletions idempotent/src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=123
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.javaboy.idempotent;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class IdempotentApplicationTests {

@Test
void contextLoads() {
}

}
Loading

0 comments on commit e4ae293

Please sign in to comment.