1.控制层
@ApiOperation(value = "学生信息保存")
@StopFormRepeatSubmitAnnotation("student:save")
@StopFormRepeatSubmitAnnotation(value = "student:save",second = 12)
@PostMapping("/save")
public R<Boolean> save(@RequestBody @Valid Student student) {
return R.ok();
}
2.注解
package com.jiayou.internethospital.common.extapi.annotation;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface StopFormRepeatSubmitAnnotation {
String value() default "";
int second() default 30;
}
3.注解AOP拦截器
package test;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.data.redis.core.RedisTemplate;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
@SuppressWarnings("unchecked")
@Slf4j
@Aspect
@AllArgsConstructor
public class StopFormRepeatSubmitInterceptor {
private final RedisTemplate redisTemplate;
@SneakyThrows
@Around("@annotation(stopFormRepeatSubmitAnnotation)")
public Object apiAopIdempotentInterceptor(ProceedingJoinPoint proceedingJoinPoint, StopFormRepeatSubmitAnnotation stopFormRepeatSubmitAnnotation) {
Object proceed = null;
String extApi = stopFormRepeatSubmitAnnotation.value();
int second = stopFormRepeatSubmitAnnotation.second();
String userId = getUserId();
if (StrUtil.isEmpty(userId)) {
HttpServletResponse response = HttpUtils.getHttpServletResponse();
HttpResultUtils.responseError(response, ResultEnum.TOKEN_LOSE_EFFICACY.getCode(), ResultEnum.TOKEN_LOSE_EFFICACY.getMessage());
return null;
}
String extApiKey = extApi + getUserId();
if (!findRepectKey(extApiKey)) {
HttpServletResponse response = HttpUtils.getHttpServletResponse();
HttpResultUtils.responseError(response, ResultEnum.REPECT_SUBMIT.getCode(), ResultEnum.REPECT_SUBMIT.getMessage());
return null;
}
try {
proceed = proceedingJoinPoint.proceed();
} catch (Throwable e) {
log.error("stopFormRepeatSubmitInterceptor :{}", ExceptionUtil.stacktraceToString(e));
redisTemplate.delete(extApiKey);
ExtApiExceptionUtils.throwThrowableException(e);
} finally {
redisTemplate.delete(extApiKey);
}
return proceed;
}
private Boolean findRepectKey(String extApiKey,int second) {
final Object objectValueByKey = redisTemplate.opsForValue().get(extApiKey);
if (Objects.isNull(objectValueByKey)) {
redisTemplate.opsForValue().set(extApiKey, extApiKey, second, TimeUnit.SECONDS);
return Boolean.TRUE;
}
return Boolean.FALSE;
}
private String getUserId() {
SystemUser user = SecurityUtils.getUser().getId();
if (Objects.isNull(user)) {
return null;
}
return user.getId().toString();
}
}
4.其他
4.1HttpUtils请求工具类
package test;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.jiayou.internethospital.common.core.entity.HttpResult;
import lombok.experimental.UtilityClass;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@UtilityClass
public class HttpUtils {
public HttpServletRequest getHttpServletRequest() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
}
public HttpServletResponse getHttpServletResponse() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
}
}
4.2 ResultEnum 返回结果枚举工具类
package test;
import lombok.Getter;
@Getter
public enum ResultEnum {
REPECT_SUBMIT(4, "系统正在处理、请勿重复提交!"),
TOKEN_LOSE_EFFICACY(10, "当前会话失效、请退出重登录再试"),
;
private Integer code;
private String message;
ResultEnum(Integer code, String message) {
this.code = code;
this.message = message;
}
}