最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

spring boot 防止重復(fù)提交實現(xiàn)方法詳解

 更新時間:2019年11月06日 10:49:11   作者:蒼青浪  
這篇文章主要介紹了spring boot 防止重復(fù)提交實現(xiàn)方法,結(jié)合實例形式詳細分析了spring boot 防止重復(fù)提交具體配置、實現(xiàn)方法及操作注意事項,需要的朋友可以參考下

本文實例講述了spring boot 防止重復(fù)提交實現(xiàn)方法。分享給大家供大家參考,具體如下:

服務(wù)器端實現(xiàn)方案:同一客戶端在2秒內(nèi)對同一URL的提交視為重復(fù)提交

上代碼吧

pom.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>
 <groupId>com.example</groupId>
 <artifactId>springboot-repeat-submit</artifactId>
 <version>1.0</version>
 <packaging>jar</packaging>
 <parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.0.4.RELEASE</version>
  <relativePath/> <!-- lookup parent from repository -->
 </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.boot</groupId>
   <artifactId>spring-boot-starter-aop</artifactId>
  </dependency>
  <dependency>
   <groupId>com.google.guava</groupId>
   <artifactId>guava</artifactId>
   <version>24.0-jre</version>
  </dependency>
 </dependencies>
 <build>
  <plugins>
   <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
   </plugin>
  </plugins>
 </build>
</project>

Application.java

package com;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
 * @author www.gaozz.club
 * @功能描述 防重復(fù)提交
 * @date 2018-08-26
 */
@SpringBootApplication
public class Application {
 public static void main(String[] args) {
  SpringApplication.run(Application.class, args);
 }
}

自定義注解NoRepeatSubmit.java

package com.common;
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) // 運行時有效
/**
 * @功能描述 防止重復(fù)提交標記注解
 * @author www.gaozz.club
 * @date 2018-08-26
 */
public @interface NoRepeatSubmit {
}

aop解析注解NoRepeatSubmitAop.java

package com.common;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
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 com.google.common.cache.Cache;
@Aspect
@Component
/**
 * @功能描述 aop解析注解
 * @author www.gaozz.club
 * @date 2018-08-26
 */
public class NoRepeatSubmitAop {
 private Log logger = LogFactory.getLog(getClass());
 @Autowired
 private Cache<String, Integer> cache;
 @Around("execution(* com.example..*Controller.*(..)) && @annotation(nrs)")
 public Object arround(ProceedingJoinPoint pjp, NoRepeatSubmit nrs) {
  try {
   ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
   String sessionId = RequestContextHolder.getRequestAttributes().getSessionId();
   HttpServletRequest request = attributes.getRequest();
   String key = sessionId + "-" + request.getServletPath();
   if (cache.getIfPresent(key) == null) {// 如果緩存中有這個url視為重復(fù)提交
    Object o = pjp.proceed();
    cache.put(key, 0);
    return o;
   } else {
    logger.error("重復(fù)提交");
    return null;
   }
  } catch (Throwable e) {
   e.printStackTrace();
   logger.error("驗證重復(fù)提交時出現(xiàn)未知異常!");
   return "{\"code\":-889,\"message\":\"驗證重復(fù)提交時出現(xiàn)未知異常!\"}";
  }
 }
}

緩存類

package com.common;
import java.util.concurrent.TimeUnit;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
@Configuration
/**
 * @功能描述 內(nèi)存緩存
 * @author www.gaozz.club
 * @date 2018-08-26
 */
public class UrlCache {
 @Bean
 public Cache<String, Integer> getCache() {
  return CacheBuilder.newBuilder().expireAfterWrite(2L, TimeUnit.SECONDS).build();// 緩存有效期為2秒
 }
}

測試Controller

package com.example;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.common.NoRepeatSubmit;
/**
 * @功能描述 測試Controller
 * @author www.gaozz.club
 * @date 2018-08-26
 */
@RestController
public class TestController {
 @RequestMapping("/test")
 @NoRepeatSubmit
 public String test() {
  return ("程序邏輯返回");
 }
}

瀏覽器輸入http://localhost:8080/test

然后F5刷新查看效果

以下為新版內(nèi)容:解決了程序集群部署時請求可能會落到多臺機器上的問題,把內(nèi)存緩存換成了redis

application.yml

spring:
 redis:
 host: 192.168.1.92
 port: 6379
 password: 123456

RedisConfig.java

package com.common;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
@Configuration
public class RedisConfig {
 @Bean
 @ConfigurationProperties(prefix = "spring.redis")
 public JedisConnectionFactory getConnectionFactory() {
  return new JedisConnectionFactory(new RedisStandaloneConfiguration(), JedisClientConfiguration.builder().build());
 }
 @Bean
 <K, V> RedisTemplate<K, V> getRedisTemplate() {
  RedisTemplate<K, V> redisTemplate = new RedisTemplate<K, V>();
  redisTemplate.setConnectionFactory(getConnectionFactory());
  return redisTemplate;
 }
}

調(diào)整切面類NoRepeatSubmitAop.java

package com.common;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
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 org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@Aspect
@Component
/**
 * @功能描述 aop解析注解
 * @author www.gaozz.club
 * @date 2018-11-02
 */
public class NoRepeatSubmitAop {
 private Log logger = LogFactory.getLog(getClass());
 @Autowired
 private RedisTemplate<String, Integer> template;
 @Around("execution(* com.example..*Controller.*(..)) && @annotation(nrs)")
 public Object arround(ProceedingJoinPoint pjp, NoRepeatSubmit nrs) {
  ValueOperations<String, Integer> opsForValue = template.opsForValue();
  try {
   ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
   String sessionId = RequestContextHolder.getRequestAttributes().getSessionId();
   HttpServletRequest request = attributes.getRequest();
   String key = sessionId + "-" + request.getServletPath();
   if (opsForValue.get(key) == null) {// 如果緩存中有這個url視為重復(fù)提交
    Object o = pjp.proceed();
    opsForValue.set(key, 0, 2, TimeUnit.SECONDS);
    return o;
   } else {
    logger.error("重復(fù)提交");
    return null;
   }
  } catch (Throwable e) {
   e.printStackTrace();
   logger.error("驗證重復(fù)提交時出現(xiàn)未知異常!");
   return "{\"code\":-889,\"message\":\"驗證重復(fù)提交時出現(xiàn)未知異常!\"}";
  }
 }
}

附:GitHub源碼地址:https://github.com/gzz2017gzz/spring-boot2-example/tree/master/54-spring-boot-repeat-submit-single

更多關(guān)于java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Spring框架入門與進階教程》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總

希望本文所述對大家java程序設(shè)計有所幫助。

相關(guān)文章

  • Java遍歷Properties所有元素的方法實例

    Java遍歷Properties所有元素的方法實例

    這篇文章主要介紹了Java如何遍歷Properties所有元素的方法,大家可以參考使用
    2013-11-11
  • 設(shè)計模式之模版方法模式_動力節(jié)點Java學(xué)院整理

    設(shè)計模式之模版方法模式_動力節(jié)點Java學(xué)院整理

    這篇文章主要介紹了設(shè)計模式之模版方法模式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • Kotlin 基礎(chǔ)教程之異常

    Kotlin 基礎(chǔ)教程之異常

    這篇文章主要介紹了Kotlin 基礎(chǔ)教程之異常的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • @RequestParam注解加與不加有什么區(qū)別

    @RequestParam注解加與不加有什么區(qū)別

    這篇文章主要介紹了@RequestParam注解加與不加有什么區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-11-11
  • Java中實現(xiàn)多重排序的幾種方法小結(jié)

    Java中實現(xiàn)多重排序的幾種方法小結(jié)

    Java中的多重排序通常指的是同時對一個集合中的兩個或更多列或多維度的數(shù)據(jù)進行排序,這通常通過自定義Comparator實現(xiàn),可以結(jié)合Arrays.sort()或Collections.sort()方法,當需要進行多重排序時,即根據(jù)多個字段進行排序,我們可以采用以下幾種方法
    2024-10-10
  • SpringBoot整合Spring?Data?JPA的詳細方法

    SpringBoot整合Spring?Data?JPA的詳細方法

    JPA全稱為Java Persistence API(Java持久層API),是一個基于ORM的標準規(guī)范,在這個規(guī)范中,JPA只定義標準規(guī)則,不提供實現(xiàn),本文重點給大家介紹SpringBoot整合Spring?Data?JPA的相關(guān)知識,感興趣的朋友一起看看吧
    2022-02-02
  • Java實現(xiàn)冪等性校驗的示例代碼

    Java實現(xiàn)冪等性校驗的示例代碼

    我們在做web應(yīng)用的時候通常會遇到前端提交按鈕重復(fù)點擊的場景,在某些新增操作上就需要做冪等性限制來保證數(shù)據(jù)的可靠性,所以本文主要介紹了如何使用java?aop實現(xiàn)冪等性校驗,需要的可以參考下
    2024-02-02
  • Java實現(xiàn)短信發(fā)送驗證碼功能

    Java實現(xiàn)短信發(fā)送驗證碼功能

    這篇文章主要介紹了Java實現(xiàn)短信發(fā)送驗證碼功能,本文通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2018-10-10
  • Java中使用DOM4J生成xml文件并解析xml文件的操作

    Java中使用DOM4J生成xml文件并解析xml文件的操作

    這篇文章主要介紹了Java中使用DOM4J來生成xml文件和解析xml文件的操作,今天通過代碼給大家展示了解析xml文件和生成xml文件的方法,需要的朋友可以參考下
    2021-09-09
  • 深入理解spring的AOP機制原理

    深入理解spring的AOP機制原理

    本篇文章主要介紹了深入理解spring的AOP機制原理,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09

最新評論

西林县| 德化县| 新泰市| 雷州市| 宜章县| 离岛区| 新巴尔虎左旗| 治县。| 友谊县| 定日县| 庄浪县| 富阳市| 巢湖市| 开平市| 巴塘县| 凤山县| 平昌县| 南溪县| 仁怀市| 玉林市| 青河县| 娱乐| 苍山县| 遵义市| 漳浦县| 兴海县| 蓝山县| 宁城县| 丹巴县| 农安县| 黄陵县| 永川市| 赤峰市| 竹山县| 两当县| 蓬安县| 武城县| 龙州县| 旺苍县| 黑水县| 弥渡县|