| | |
| | | import cn.hutool.core.util.ArrayUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.crypto.SecureUtil; |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import org.aspectj.lang.JoinPoint; |
| | | import org.aspectj.lang.annotation.AfterReturning; |
| | | import org.aspectj.lang.annotation.AfterThrowing; |
| | | import org.aspectj.lang.annotation.Aspect; |
| | | import org.aspectj.lang.annotation.Before; |
| | | import org.dromara.common.core.constant.GlobalConstants; |
| | | import org.dromara.common.core.context.ThreadLocalHolder; |
| | | import org.dromara.common.core.domain.R; |
| | | import org.dromara.common.core.exception.ServiceException; |
| | | import org.dromara.common.core.utils.MessageUtils; |
| | |
| | | import org.dromara.common.idempotent.annotation.RepeatSubmit; |
| | | import org.dromara.common.json.utils.JsonUtils; |
| | | import org.dromara.common.redis.utils.RedisUtils; |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import org.aspectj.lang.JoinPoint; |
| | | import org.aspectj.lang.annotation.AfterReturning; |
| | | import org.aspectj.lang.annotation.AfterThrowing; |
| | | import org.aspectj.lang.annotation.Aspect; |
| | | import org.aspectj.lang.annotation.Before; |
| | | import org.springframework.validation.BindingResult; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | |
| | | @Aspect |
| | | public class RepeatSubmitAspect { |
| | | |
| | | private static final String KEY_CACHE = "keyCache"; |
| | | private static final ThreadLocal<String> KEY_CACHE = new ThreadLocal<>(); |
| | | |
| | | @Before("@annotation(repeatSubmit)") |
| | | public void doBefore(JoinPoint point, RepeatSubmit repeatSubmit) throws Throwable { |
| | |
| | | // 唯一标识(指定key + url + 消息头) |
| | | String cacheRepeatKey = GlobalConstants.REPEAT_SUBMIT_KEY + url + submitKey; |
| | | if (RedisUtils.setObjectIfAbsent(cacheRepeatKey, "", Duration.ofMillis(interval))) { |
| | | ThreadLocalHolder.set(KEY_CACHE, cacheRepeatKey); |
| | | KEY_CACHE.set(cacheRepeatKey); |
| | | } else { |
| | | String message = repeatSubmit.message(); |
| | | if (StringUtils.startsWith(message, "{") && StringUtils.endsWith(message, "}")) { |
| | |
| | | if (r.getCode() == R.SUCCESS) { |
| | | return; |
| | | } |
| | | String cacheKey = ThreadLocalHolder.get(KEY_CACHE); |
| | | RedisUtils.deleteObject(cacheKey); |
| | | RedisUtils.deleteObject(KEY_CACHE.get()); |
| | | } finally { |
| | | ThreadLocalHolder.remove(KEY_CACHE); |
| | | KEY_CACHE.remove(); |
| | | } |
| | | } |
| | | } |
| | |
| | | */ |
| | | @AfterThrowing(value = "@annotation(repeatSubmit)", throwing = "e") |
| | | public void doAfterThrowing(JoinPoint joinPoint, RepeatSubmit repeatSubmit, Exception e) { |
| | | String cacheKey = ThreadLocalHolder.get(KEY_CACHE); |
| | | RedisUtils.deleteObject(cacheKey); |
| | | ThreadLocalHolder.remove(KEY_CACHE); |
| | | RedisUtils.deleteObject(KEY_CACHE.get()); |
| | | KEY_CACHE.remove(); |
| | | } |
| | | |
| | | /** |
| | |
| | | public boolean isFilterObject(final Object o) { |
| | | Class<?> clazz = o.getClass(); |
| | | if (clazz.isArray()) { |
| | | return clazz.getComponentType().isAssignableFrom(MultipartFile.class); |
| | | return MultipartFile.class.isAssignableFrom(clazz.getComponentType()); |
| | | } else if (Collection.class.isAssignableFrom(clazz)) { |
| | | Collection collection = (Collection) o; |
| | | for (Object value : collection) { |