国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

SpringBoot 整合redis + Aop防止重復(fù)提交 (簡易)

這篇具有很好參考價值的文章主要介紹了SpringBoot 整合redis + Aop防止重復(fù)提交 (簡易)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1.redis的安裝

redis下載 解壓 安裝

# wget http://download.redis.io/releases/redis-6.0.8.tar.gz
# tar xzf redis-6.0.8.tar.gz
# cd redis-6.0.8
# make

看一下就會有SpringBoot 整合redis + Aop防止重復(fù)提交 (簡易),spring boot,redis,java

?進(jìn)入redis-6.0.8下的src目錄

[root@VM-16-8-centos redis]# cd redis-6.0.8
[root@VM-16-8-centos redis-6.0.8]# cd src

(? src?目錄下有編譯后的 redis 服務(wù)程序 redis-server,還有用于測試的客戶端程序 redis-cli:)

然后啟動

# ./redis-server ../redis.conf

SpringBoot 整合redis + Aop防止重復(fù)提交 (簡易),spring boot,redis,java

redis默認(rèn)端口號 6379,建議更改。redis.conf是配置文件在? 與src是同級目錄。

要遠(yuǎn)程? #去掉保護(hù)模式,注釋掉bind:127.0.0.1,protected-mode 改為no,

此外就是?redis 安全問題需要考慮,不然服務(wù)器會被入侵被挖礦 ,必須

#設(shè)置密碼 requirepass 你的密碼? ? (大約在 redis.conf 的 790 行)

設(shè)置密碼后 ,啟動 redis 服務(wù)進(jìn)程后,就可以使用測試客戶端程序 redis-cli 和 redis 服務(wù)交互了

./redis.cli? -p 端口號 -a? 你的密碼

2.SpringBoot整合redis

首先?IDEA?創(chuàng)建好一個SpringBoot 的 web 項(xiàng)目。

1.導(dǎo)入依賴:

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

2.新建application.yml配置

spring:
  redis:
    # Redis本地服務(wù)器地址,注意要開啟redis服務(wù),即那個redis-server.exe
    host: 你的服務(wù)器地址
    # Redis服務(wù)器端口,默認(rèn)為6379.若有改動按改動后的來
    port: 端口號
    #Redis服務(wù)器連接密碼,默認(rèn)為空,若有設(shè)置按設(shè)置的來
    password: 密碼
    lettuce:
      pool:
        # 連接池最大連接數(shù),若為負(fù)數(shù)則表示沒有任何限制
        max-active: 8
        # 連接池最大阻塞等待時間,若為負(fù)數(shù)則表示沒有任何限制
        max-wait: -1
        # 連接池中的最大空閑連接
        max-idle: 8

3.redis配置類-直接用


import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * redis配置類
 */
@Configuration
@EnableCaching //開啟注解
public class RedisConfig extends CachingConfigurerSupport {

    /**
     * retemplate相關(guān)配置
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {

        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 配置連接工廠
        template.setConnectionFactory(factory);

        //使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值(默認(rèn)使用JDK的序列化方式)
        Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);

        ObjectMapper om = new ObjectMapper();
        // 指定要序列化的域,field,get和set,以及修飾符范圍,ANY是都有包括private和public
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化輸入的類型,類必須是非final修飾的,final修飾的類,比如String,Integer等會跑出異常
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jacksonSeial.setObjectMapper(om);

        // 值采用json序列化
        template.setValueSerializer(jacksonSeial);
        //使用StringRedisSerializer來序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());

        // 設(shè)置hash key 和value序列化模式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(jacksonSeial);
        template.afterPropertiesSet();

        return template;
    }

    /**
     * 對hash類型的數(shù)據(jù)操作
     */
    @Bean
    public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForHash();
    }

    /**
     * 對redis字符串類型數(shù)據(jù)操作
     */
    @Bean
    public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForValue();
    }

    /**
     * 對鏈表類型的數(shù)據(jù)操作
     */
    @Bean
    public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForList();
    }

    /**
     * 對無序集合類型的數(shù)據(jù)操作
     */
    @Bean
    public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForSet();
    }

    /**
     * 對有序集合類型的數(shù)據(jù)操作
     */
    @Bean
    public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForZSet();
    }

}

4.redis工具類-直接用


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

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Component
public class RedisUtil {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    public RedisUtil(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 指定緩存失效時間
     * @param key 鍵
     * @param time 時間(秒)
     * @return
     */
    public boolean expire(String key,long time){
        try {
            if(time>0){
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根據(jù)key 獲取過期時間
     * @param key 鍵 不能為null
     * @return 時間(秒) 返回0代表為永久有效
     */
    public long getExpire(String key){
        return redisTemplate.getExpire(key,TimeUnit.SECONDS);
    }

    /**
     * 判斷key是否存在
     * @param key 鍵
     * @return true 存在 false不存在
     */
    public boolean hasKey(String key){
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 刪除緩存
     * @param key 可以傳一個值 或多個
     */
    @SuppressWarnings("unchecked")
    public void del(String ... key){
        if(key!=null&&key.length>0){
            if(key.length==1){
                redisTemplate.delete(key[0]);
            }else{
                redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
            }
        }
    }

    //============================String=============================
    /**
     * 普通緩存獲取
     * @param key 鍵
     * @return 值
     */
    public Object get(String key){
        return key==null?null:redisTemplate.opsForValue().get(key);
    }

    /**
     * 普通緩存放入
     * @param key 鍵
     * @param value 值
     * @return true成功 false失敗
     */
    public boolean set(String key,Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 普通緩存放入并設(shè)置時間
     * @param key 鍵
     * @param value 值
     * @param time 時間(秒) time要大于0 如果time小于等于0 將設(shè)置無限期
     * @return true成功 false 失敗
     */
    public boolean set(String key,Object value,long time){
        try {
            if(time>0){
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            }else{
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 遞增
     * @param key 鍵
     * @param delta 要增加幾(大于0)
     * @return
     */
    public long incr(String key, long delta){
        if(delta<0){
            throw new RuntimeException("遞增因子必須大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /**
     * 遞減
     * @param key 鍵
     * @param delta 要減少幾(小于0)
     * @return
     */
    public long decr(String key, long delta){
        if(delta<0){
            throw new RuntimeException("遞減因子必須大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }

    //================================Map=================================
    /**
     * HashGet
     * @param key 鍵 不能為null
     * @param item 項(xiàng) 不能為null
     * @return 值
     */
    public Object hget(String key,String item){
        return redisTemplate.opsForHash().get(key, item);
    }

    /**
     * 獲取hashKey對應(yīng)的所有鍵值
     * @param key 鍵
     * @return 對應(yīng)的多個鍵值
     */
    public Map<Object,Object> hmget(String key){
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * HashSet
     * @param key 鍵
     * @param map 對應(yīng)多個鍵值
     * @return true 成功 false 失敗
     */
    public boolean hmset(String key, Map<String,Object> map){
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * HashSet 并設(shè)置時間
     * @param key 鍵
     * @param map 對應(yīng)多個鍵值
     * @param time 時間(秒)
     * @return true成功 false失敗
     */
    public boolean hmset(String key, Map<String,Object> map, long time){
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if(time>0){
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一張hash表中放入數(shù)據(jù),如果不存在將創(chuàng)建
     * @param key 鍵
     * @param item 項(xiàng)
     * @param value 值
     * @return true 成功 false失敗
     */
    public boolean hset(String key,String item,Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一張hash表中放入數(shù)據(jù),如果不存在將創(chuàng)建
     * @param key 鍵
     * @param item 項(xiàng)
     * @param value 值
     * @param time 時間(秒)  注意:如果已存在的hash表有時間,這里將會替換原有的時間
     * @return true 成功 false失敗
     */
    public boolean hset(String key,String item,Object value,long time) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if(time>0){
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 刪除hash表中的值
     * @param key 鍵 不能為null
     * @param item 項(xiàng) 可以使多個 不能為null
     */
    public void hdel(String key, Object... item){
        redisTemplate.opsForHash().delete(key,item);
    }

    /**
     * 判斷hash表中是否有該項(xiàng)的值
     * @param key 鍵 不能為null
     * @param item 項(xiàng) 不能為null
     * @return true 存在 false不存在
     */
    public boolean hHasKey(String key, String item){
        return redisTemplate.opsForHash().hasKey(key, item);
    }

    /**
     * hash遞增 如果不存在,就會創(chuàng)建一個 并把新增后的值返回
     * @param key 鍵
     * @param item 項(xiàng)
     * @param by 要增加幾(大于0)
     * @return
     */
    public double hincr(String key, String item,double by){
        return redisTemplate.opsForHash().increment(key, item, by);
    }

    /**
     * hash遞減
     * @param key 鍵
     * @param item 項(xiàng)
     * @param by 要減少記(小于0)
     * @return
     */
    public double hdecr(String key, String item,double by){
        return redisTemplate.opsForHash().increment(key, item,-by);
    }

    //============================set=============================
    /**
     * 根據(jù)key獲取Set中的所有值
     * @param key 鍵
     * @return
     */
    public Set<Object> sGet(String key){
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根據(jù)value從一個set中查詢,是否存在
     * @param key 鍵
     * @param value 值
     * @return true 存在 false不存在
     */
    public boolean sHasKey(String key,Object value){
        try {
            return redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 將數(shù)據(jù)放入set緩存
     * @param key 鍵
     * @param values 值 可以是多個
     * @return 成功個數(shù)
     */
    public long sSet(String key, Object...values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 將set數(shù)據(jù)放入緩存
     * @param key 鍵
     * @param time 時間(秒)
     * @param values 值 可以是多個
     * @return 成功個數(shù)
     */
    public long sSetAndTime(String key,long time,Object...values) {
        try {
            Long count = redisTemplate.opsForSet().add(key, values);
            if(time>0) {
                expire(key, time);
            }
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 獲取set緩存的長度
     * @param key 鍵
     * @return
     */
    public long sGetSetSize(String key){
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 移除值為value的
     * @param key 鍵
     * @param values 值 可以是多個
     * @return 移除的個數(shù)
     */
    public long setRemove(String key, Object ...values) {
        try {
            Long count = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    //===============================list=================================

    /**
     * 獲取list緩存的內(nèi)容
     * @param key 鍵
     * @param start 開始
     * @param end 結(jié)束  0 到 -1代表所有值
     * @return
     */
    public List<Object> lGet(String key, long start, long end){
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 獲取list緩存的長度
     * @param key 鍵
     * @return
     */
    public long lGetListSize(String key){
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 通過索引 獲取list中的值
     * @param key 鍵
     * @param index 索引  index>=0時, 0 表頭,1 第二個元素,依次類推;index<0時,-1,表尾,-2倒數(shù)第二個元素,依次類推
     * @return
     */
    public Object lGetIndex(String key,long index){
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 將list放入緩存
     * @param key 鍵
     * @param value 值
     * @return
     */
    public boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 將list放入緩存
     * @param key 鍵
     * @param value 值
     * @param time 時間(秒)
     * @return
     */
    public boolean lSet(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 將list放入緩存
     * @param key 鍵
     * @param value 值
     * @return
     */
    public boolean lSet(String key, List<Object> value) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 將list放入緩存
     * @param key 鍵
     * @param value 值
     * @param time 時間(秒)
     * @return
     */
    public boolean lSet(String key, List<Object> value, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根據(jù)索引修改list中的某條數(shù)據(jù)
     * @param key 鍵
     * @param index 索引
     * @param value 值
     * @return
     */
    public boolean lUpdateIndex(String key, long index,Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 移除N個值為value
     * @param key 鍵
     * @param count 移除多少個
     * @param value 值
     * @return 移除的個數(shù)
     */
    public long lRemove(String key,long count,Object value) {
        try {
            Long remove = redisTemplate.opsForList().remove(key, count, value);
            return remove;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

}

5.寫Controller測試


import com.qcby.bootredis.NoRepeatSubmit;
import com.qcby.bootredis.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;


@Slf4j
@RequestMapping("/redis")
@RestController
public class RedisController {


    @Resource
    private RedisUtil redisUtil;

    @RequestMapping("set")
   // @NoRepeatSubmit
    public boolean redisset(String key, String value){
        System.out.println(key+"--"+value);
        return redisUtil.set(key,value);
    }

    @RequestMapping("get")
    public Object redisget(String key){
        System.out.println(redisUtil.get(key));
        return redisUtil.get(key);
    }

    @RequestMapping("expire")
    public boolean expire(String key,long ExpireTime){
        return redisUtil.expire(key,ExpireTime);
    }
}

6.啟動redis,啟動程序,存?zhèn)€數(shù)據(jù),測試結(jié)果

SpringBoot 整合redis + Aop防止重復(fù)提交 (簡易),spring boot,redis,java

?拿個數(shù)據(jù):

SpringBoot 整合redis + Aop防止重復(fù)提交 (簡易),spring boot,redis,java

?redis中:

SpringBoot 整合redis + Aop防止重復(fù)提交 (簡易),spring boot,redis,java

3.整合AOP,防止重復(fù)提交

 一,定義注解。

    定義一個鎖住接口時間的方法,默認(rèn)值為5。

import java.lang.annotation.*;

@Documented
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface NoRepeatSubmit {
    int lockTime() default 5;
}

二,寫一個HttpContextUtil工具類獲取HttpServletRequest請求

import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

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

public class HttpContextUtils {
    public static HttpServletRequest HttpServletRequest(){
        return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
    }
}

 三,定義一個切面

    采用的方案是Redis來緩存提交接口的唯一標(biāo)識,然后設(shè)置過期時間。

唯一標(biāo)識使用接口的URL和用戶的token組合在一起的方式使達(dá)到唯一。用戶每發(fā)起第一次添加請求,會經(jīng)過界面,在切面獲取信息后組裝起來存入Redis,當(dāng)用戶后續(xù)發(fā)起請求時,首先判斷Redis中是否緩存了這個key,如果緩存了,則證明已經(jīng)提交,于是反饋給前端,如果不存在,證明沒有提交,則存入Redis。

@Component
@Aspect
public class NoRepeatSubmitAspect {
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Pointcut("@annotation(repeatSubmit)")
    public void pointcutNoRepeat(NoRepeatSubmit repeatSubmit){};
    @Around("pointcutNoRepeat(noRepeatSubmit)")
    public Object doNoRepeat(ProceedingJoinPoint point,NoRepeatSubmit noRepeatSubmit) throws Throwable {
        int i=noRepeatSubmit.lockTime();
        HttpServletRequest httpServletRequest = HttpContextUtils.HttpServletRequest();
        String token = httpServletRequest.getHeader("token");
        String url = httpServletRequest.getRequestURL().toString();
        String sign = url+"/"+token;
        Boolean key=redisTemplate.hasKey(sign);
        if (key){
            throw new Exception("請勿重復(fù)提交");
        }
        redisTemplate.opsForValue().set(sign,sign,i,TimeUnit.SECONDS);
        return  point.proceed();
    }
}
如果key存在拋出異常。
@Aspect:聲明這是一個切面類(使用時需要與@Component注解一起用,表明同時將該類交給spring管理)

@pointcut(@annotation)是Spring AOP中的一個注解,它可以用來指定一個切點(diǎn),該切點(diǎn)選擇所有帶有特定注解的方法或類。例如,如果我們想要記錄所有帶有@Log注解的方法的日志,我們可以定義一個切點(diǎn),使用@pointcut(@annotation(Log.class)注解來選擇這些方法。

@Around 環(huán)繞通知

?point.proceed():

  1. 環(huán)繞通知 ProceedingJoinPoint?執(zhí)行proceed方法的作用是讓目標(biāo)方法執(zhí)行,這也是環(huán)繞通知和前置、后置通知方法的一個最大區(qū)別。
  2. 簡單理解,環(huán)繞通知=前置+目標(biāo)方法執(zhí)行+后置通知,proceed方法就是用于啟動目標(biāo)方法執(zhí)行的.

四。之前方法上加上我們的注解?

SpringBoot 整合redis + Aop防止重復(fù)提交 (簡易),spring boot,redis,java

?結(jié)果:第一次,添加完成,緊接著第二次發(fā)送,拋出了我們的異常

?https://www.cnblogs.com/steakliu/p/14769034.html文章來源地址http://www.zghlxwxcb.cn/news/detail-531742.html

到了這里,關(guān)于SpringBoot 整合redis + Aop防止重復(fù)提交 (簡易)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • springBoot防止重復(fù)提交

    springBoot防止重復(fù)提交

    兩種方法, 一種是后端實(shí)現(xiàn),較復(fù)雜,要通過自定義注解和AOP以及Redis組合實(shí)現(xiàn) 另一種是前端實(shí)現(xiàn),簡單,只需通過js,設(shè)置過期時間,一定時間內(nèi),多次點(diǎn)擊按鈕只生效一次 自定義注解+AOP+Redis 自定義異常類和全局異常處理 自定義異常類:CustomException 全局異常處理:Cust

    2024年02月11日
    瀏覽(21)
  • 前端如何防止接口重復(fù)提交

    接口重復(fù)提交指的是在網(wǎng)絡(luò)通信中,同一個請求被客戶端多次發(fā)送到服務(wù)器端的情況。這種情況可能由于多種原因?qū)е拢缬脩粼诘却陂g多次點(diǎn)擊提交按鈕、網(wǎng)絡(luò)超時后客戶端重新發(fā)送請求、客戶端發(fā)送的請求在網(wǎng)絡(luò)傳輸過程中出現(xiàn)重復(fù)等。 接口重復(fù)提交可能會導(dǎo)致多種

    2024年04月22日
    瀏覽(28)
  • 防止重復(fù)提交請求

    防止重復(fù)提交請求

    前景提要: ts 簡易封裝 axios,統(tǒng)一 API 實(shí)現(xiàn)在 config 中配置開關(guān)攔截器 axios 實(shí)現(xiàn)請求 loading 效果 用一個數(shù)組保存當(dāng)前請求的 url,此時還未響應(yīng)。如果再次發(fā)起同樣請求,比對 url 發(fā)現(xiàn)已經(jīng)存在數(shù)組中,則攔截請求,提示重復(fù)提交。當(dāng)該請求響應(yīng)結(jié)束后,就將 url 從數(shù)組中剔除

    2024年02月06日
    瀏覽(22)
  • 微信小程序防止重復(fù)提交

    微信小程序在真機(jī)測試時,遇到這樣一種情況:當(dāng)網(wǎng)絡(luò)條件差或卡頓的情況下,進(jìn)行某項(xiàng)操作時,使用者會認(rèn)為點(diǎn)擊無效而進(jìn)行多次點(diǎn)擊,致使多次跳轉(zhuǎn)頁面或多次上傳同一表單,導(dǎo)致函數(shù)或接口被多次調(diào)用,實(shí)際上使用者只想調(diào)用函數(shù)和接口一次。 添加節(jié)流閥,即按下按鈕

    2024年02月13日
    瀏覽(32)
  • java防止重復(fù)提交的方法

    java防止重復(fù)提交的方法

    ? 為了防止重復(fù)提交,可以采用以下幾種方法: 1.?令牌機(jī)制(Token) 在表單中添加一個隱藏字段,用于存放一個隨機(jī)生成的令牌(Token)。當(dāng)用戶提交表單時,將令牌一起提交到服務(wù)器。服務(wù)器接收到請求后,首先檢查令牌是否存在,如果不存在則拒絕請求;如果存在,則將

    2024年02月01日
    瀏覽(23)
  • 【springboot】spring的Aop結(jié)合Redis實(shí)現(xiàn)對短信接口的限流

    【springboot】spring的Aop結(jié)合Redis實(shí)現(xiàn)對短信接口的限流

    場景: 為了限制短信驗(yàn)證碼接口的訪問次數(shù),防止被刷,結(jié)合Aop和redis根據(jù)用戶ip對用戶限流 首先我們創(chuàng)建一個 Spring Boot 工程,引入 Web 和 Redis 依賴,同時考慮到接口限流一般是通過注解來標(biāo)記,而注解是通過 AOP 來解析的,所以我們還需要加上 AOP 的依賴,最終的依賴如下:

    2024年02月05日
    瀏覽(21)
  • HTML5中form表單防止重復(fù)提交的兩種方法

    form表單重復(fù)提交是在多用戶Web應(yīng)用中最常見、帶來很多麻煩的一個問題。有很多的應(yīng)用場景都會遇到重復(fù)提交問題 (1)點(diǎn)擊提交按鈕兩次。 (2)點(diǎn)擊刷新按鈕。 (3)使用瀏覽器后退按鈕重復(fù)之前的操作 導(dǎo)致重復(fù)提交表單。 (4)瀏覽器重復(fù)的HTTP請求。 (5)用戶提交表單時可能因?yàn)榫W(wǎng)

    2024年01月22日
    瀏覽(45)
  • Redis(發(fā)布訂閱、事務(wù)、redis整合springboot、集成 Spring Cache)

    Redis(發(fā)布訂閱、事務(wù)、redis整合springboot、集成 Spring Cache)

    目錄 一.redis的發(fā)布訂閱 1、什么 是發(fā)布和訂閱 2、Redis的發(fā)布和訂閱 3、發(fā)布訂閱的代碼實(shí)現(xiàn) 二.Redis事務(wù) 1.事務(wù)簡介 1、在事務(wù)執(zhí)行之前 如果監(jiān)聽的key的值有變化就不能執(zhí)行 2、在事務(wù)執(zhí)行之前 如果監(jiān)聽的key的值沒有變化就能執(zhí)行 3、Exec之前就出現(xiàn)錯誤 4、Exec之后出現(xiàn)的錯誤

    2024年01月24日
    瀏覽(18)
  • springboot(spring)整合redis(集群)、細(xì)節(jié)、底層配置講解

    springboot(spring)整合redis(集群)、細(xì)節(jié)、底層配置講解

    1.引入依賴. ? ? ?其實(shí)springboot整合其他主流框架直接在后面加上名稱即可,比如spring-boot-starter-redis,然后就直接可以用,可以直接注入了. ? ? ?主要原因大概就是springboot框架已經(jīng)包含了自動注入的功能,對于每一個引入的主要jar包(包含starter),都有一個factory的配置文件,里面配置

    2024年02月09日
    瀏覽(20)
  • 【Spring】SpringBoot整合Redis,用Redis實(shí)現(xiàn)限流(附Redis解壓包)

    【Spring】SpringBoot整合Redis,用Redis實(shí)現(xiàn)限流(附Redis解壓包)

    ? ???個人主頁:哈__ 期待您的關(guān)注? 本文介紹SpringBoot整合Redis并且進(jìn)行接口的限流,文章主要介紹的是一種思想,具體代碼還要結(jié)合實(shí)際。 Redis的解壓包我放在了百度網(wǎng)盤上,有需要的可以下載。 Redis-x64-3.0.504 解壓碼:uhwj 我們在本地解壓下載的Redis壓縮包,打開解壓后的

    2024年04月09日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包