SpringBoot防止表单重复提交+token+表单内容
第一步: 编写自定义注解.
编写自定义注解.
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NoRepeatSubmit {
long time() default 5L;
}
第二步:接口防重复切面实现.
接口防重复切面实现.
@Aspect
@Component
public class NoRepeatSubmitAop {
@Resource
private RedisService redisCache;
private static final String JWT_TOKEN_KEY = "authorization";
@Pointcut("@annotation(com.SpringBoot.annotation.NoRepeatSubmit)")
public void serviceNoRepeat() {
}
@Around("serviceNoRepeat()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
HttpServletRequest request = ServletUtils.getRequest();
String jwtToken = request.getHeader(JWT_TOKEN_KEY);
Map<String, Object> map = new HashMap<String, Object>();
Object[] values = pjp.getArgs();
String[] names = ((CodeSignature) pjp.getSignature()).getParameterNames();
for (int i = 0; i < names.length; i++) {
map.put(names[i], values[i]);
}
String body = JSONObject.toJSONString(map);
String key = Md5Util.md5(jwtToken+request.getMethod()+request.getRequestURI()+body);
if (redisCache.getCacheObject(key) == null) {
try {
Object o = pjp.proceed();
MethodSignature signature = (MethodSignature) pjp.getSignature();
NoRepeatSubmit noRepeatSubmit = signature.getMethod().getAnnotation(NoRepeatSubmit.class);
redisCache.setCacheObject(key,body,noRepeatSubmit.time(),TimeUnit.SECONDS);
return o;
}catch (Exception e){
throw new ServiceException(e.getMessage());
}
} else {
throw new ServiceException("重复提交,请稍后再试");
}
}
}
md5 工具类
public class Md5Util {
private static final Logger log = LoggerFactory.getLogger(Md5Util.class);
public static String MD5Util(String string, String salt) {
return getMD5_32(string + salt);
}
public static String getMD5_32(String src) {
try {
StringBuffer stringBuffer = new StringBuffer();
char[] chars = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] data = md.digest(src.getBytes());
for (byte b : data) {
stringBuffer.append(chars[(b >> 4) & 0x0F]);
stringBuffer.append(chars[b & 0x0F]);
}
return stringBuffer.toString();
} catch (Exception e) {
log.error("[大写MD5生成error]");
}
return null;
}
public static String md5(String str) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(str.getBytes());
byte b[] = md.digest();
int i;
StringBuffer buf = new StringBuffer("");
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0) {
i += 256;
}
if (i < 16) {
buf.append("0");
}
buf.append(Integer.toHexString(i));
}
str = buf.toString();
} catch (Exception e) {
log.error("[小写MD5生成error]");
}
return str;
}
redis 这块代码比较简单…这里就省略了
接口防重复切面的代码中: ‘authorization’
请个各位大佬多指教
|