java防止重復提交、防止重復點擊

1.引入redis

<dependency>?

? ? <groupId>org.springframework.boot</groupId>

? ? <artifactId>spring-boot-starter-data-redis</artifactId>

</dependency>

2.yml配置

spring:?

?redis:?

?????host: localhost

? ? ?port: 6379? ??

? ? ?password: 123456

3.自定義注解

import java.lang.annotation.*;

@Target({ElementType.METHOD})

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Inherited

public @interface RedisLock {

? ? int expire() default 5;

}

4. 定義切面類

import com.alibaba.fastjson.JSONObject;

import com.google.common.collect.Lists;

import com.heshu.sz.blockchain.utonhsbs.common.utils.MyMD5Util;

import com.heshu.sz.blockchain.utonhsbs.common.utils.SecurityUtils;

import com.heshu.sz.blockchain.utonhsbs.common.utils.ip.IpUtils;

import com.heshu.sz.blockchain.utonhsbs.framework.interceptor.annotation.RedisLock;

import com.heshu.sz.blockchain.utonhsbs.framework.system.domain.BaseResult;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang3.StringUtils;

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.Around;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Pointcut;

import org.aspectj.lang.reflect.MethodSignature;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.context.annotation.Configuration;

import org.springframework.data.redis.core.StringRedisTemplate;

import org.springframework.data.redis.core.script.DefaultRedisScript;

import org.springframework.data.redis.core.script.RedisScript;

import org.springframework.web.context.request.RequestAttributes;

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

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

import javax.servlet.http.HttpServletRequest;

import java.lang.reflect.Method;

import java.security.NoSuchAlgorithmException;

import java.util.ArrayList;

import java.util.List;

/**

* @author :xx

* @description:

* @date : 2022/7/1 9:41

*/

@Slf4j

@Aspect

@Configuration

public class RedisLockMethodInterceptor {

? ? @Value("${spring.profiles.active}")

? ? private String springProfilesActive;

? ? @Value("${spring.application.name}")

? ? private String springApplicationName;

? ? @Autowired

? ? private StringRedisTemplate stringRedisTemplate;

? ? @Pointcut("@annotation(com.heshu.sz.blockchain.utonhsbs.framework.interceptor.annotation.RedisLock)")

? ? public void point() {

? ? }

? ? @Around("point()")

? ? public Object doaround(ProceedingJoinPoint joinPoint) {

? ? ? ? MethodSignature signature = (MethodSignature) joinPoint.getSignature();

? ? ? ? Method method = signature.getMethod();

? ? ? ? RedisLock localLock = method.getAnnotation(RedisLock.class);

? ? ? ? try {

? ? ? ? ? ? String lockUniqueKey = getLockUniqueKey(signature, joinPoint.getArgs());

? ? ? ? ? ? Integer expire = localLock.expire();

? ? ? ? ? ? if (expire < 0) {

? ? ? ? ? ? ? ? expire = 5;

? ? ? ? ? ? }

? ? ? ? ? ? ArrayList<String> keys = Lists.newArrayList(lockUniqueKey);

? ? ? ? ? ? String result = stringRedisTemplate.execute(setNxWithExpireTime, keys, expire.toString());

? ? ? ? ? ? if (!"ok".equalsIgnoreCase(result)) {//不存在

? ? ? ? ? ? ? ? return BaseResult.error("不允許重復提交,請稍后再試");

? ? ? ? ? ? }

? ? ? ? ? ? return joinPoint.proceed();

? ? ? ? } catch (Throwable throwable) {

? ? ? ? ? ? throw new RuntimeException(throwable.getMessage());

? ? ? ? }

? ? }

? ? /**

? ? * lua腳本

? ? */

? ? private RedisScript<String> setNxWithExpireTime = new DefaultRedisScript<>(

? ? ? ? ? ? "return redis.call('set', KEYS[1], 1, 'ex', ARGV[1], 'nx');",

? ? ? ? ? ? String.class

? ? );

? ? /**

? ? * 獲取唯一標識key

? ? *

? ? * @param methodSignature

? ? * @param args

? ? * @return

? ? */

? ? private String getLockUniqueKey(MethodSignature methodSignature, Object[] args) throws NoSuchAlgorithmException {

? ? ? ? //請求uri, 獲取類名稱,方法名稱

? ? ? ? RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

? ? ? ? ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;

? ? ? ? HttpServletRequest request = servletRequestAttributes.getRequest();

//? ? ? ? HttpServletResponse responese = servletRequestAttributes.getResponse();

? ? ? ? //獲取用戶信息

? ? ? ? String userMsg = SecurityUtils.getUsername(); //獲取登錄用戶名稱

? ? ? ? //1.判斷用戶是否登錄

? ? ? ? if (StringUtils.isEmpty(userMsg)) { //未登錄用戶獲取真實ip

? ? ? ? ? ? userMsg = IpUtils.getIpAddr(request);

? ? ? ? }

? ? ? ? String hash = "";

? ? ? ? List list = new ArrayList();

? ? ? ? if (args.length > 0) {

? ? ? ? ? ? String[] parameterNames = methodSignature.getParameterNames();

? ? ? ? ? ? for (int i = 0; i < parameterNames.length; i++) {

? ? ? ? ? ? ? ? Object obj = args[i];

? ? ? ? ? ? ? ? list.add(obj);

? ? ? ? ? ? }

? ? ? ? ? ? String param = JSONObject.toJSONString(list);

? ? ? ? ? ? hash = MyMD5Util.getMD5(param);

? ? ? ? }

? ? ? ? //項目名稱 + 環(huán)境編碼 + 獲取類名稱 + 加密參數(shù)

? ? ? ? String key = "lock:" + springApplicationName + ":" + springProfilesActive + ":" + userMsg + ":" + request.getRequestURI();

? ? ? ? if (StringUtils.isNotEmpty(key)) {

? ? ? ? ? ? key = key + ":" + hash;

? ? ? ? }

? ? ? ? return key;

? ? }

5.調(diào)用

@RedisLock?

?public void save(@RequestBody User user) {

? ? }

文章來源:https://blog.csdn.net/qq_33454058/article/details/125516310?spm=1001.2014.3001.5506

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容