java实现防止重复提交

java实现防止重复提交
概念

防止重复提交是一种常见的安全措施,用于防止用户在短时间内多次提交相同的请求。通过使用注解,我们可以在代码层面实现这种防护机制,以提高系统的安全性和稳定性。

场景

防止重复提交的机制在许多Web应用程序中都是必需的,特别是在涉及到敏感操作或需要保证数据一致性的情况下。以下是一些常见的场景:

  1. 提交表单:防止用户多次提交表单,避免重复插入或修改数据。
  2. 支付请求:防止用户多次点击支付按钮,避免重复扣款。
  3. 并发操作:防止多个线程同时执行相同的操作,避免数据冲突。
其他方式

除了使用注解,还有其他一些方式可以实现防止重复提交的机制,例如:

  1. Token验证:在每个请求中生成一个唯一的令牌,并将其存储在会话或隐藏表单字段中。服务器在处理请求时验证令牌的唯一性,如果重复提交相同的令牌,则拒绝处理。
  2. 重定向:在处理请求后,将用户重定向到一个结果页面,而不是直接返回结果。这样,用户无法通过刷新页面或再次提交相同的请求。
  3. 前端验证:在前端使用JavaScript等技术验证用户输入,避免重复提交无效的请求。
步骤

下面是使用注解实现防止重复提交的一般步骤:

  1. 定义注解:创建一个自定义注解,用于标记需要进行重复提交检查的方法或接口。

  1. 实现拦截器或切面:创建一个拦截器或切面,用于在方法执行前进行重复提交检查。如下是实现一个拦截器

jrhz.info

/**

* 验证是否重复提交

* @param request

* @return

* @throws Exception

*/

public abstract boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation);

定义一个实现类,继承拦截器这个类,实现其方法具体的验证方法也在其中

类中的具体方法如下

@Override

public boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation)

{

String nowParams = "";

if (request instanceof RepeatedlyRequestWrapper)

{

RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request;

nowParams = HttpHelper.getBodyString(repeatedlyRequest);

}

// body参数为空,获取Parameter的数据

if (StringUtils.isEmpty(nowParams))

{

nowParams = JSONObject.toJSONString(request.getParameterMap());

}

Map<String, Object> nowDataMap = new HashMap<String, Object>();

nowDataMap.put(REPEAT_PARAMS, nowParams);

nowDataMap.put(REPEAT_TIME, System.currentTimeMillis());

// 请求地址(作为存放cache的key值)

String url = request.getRequestURI();

// 唯一值(没有消息头则使用请求地址)

String submitKey = StringUtils.trimToEmpty(request.getHeader(header));

// 唯一标识(指定key + url + 消息头)

String cacheRepeatKey = Constants.REPEAT_SUBMIT_KEY + url + submitKey;

Object sessionObj = redisCache.getCacheObject(cacheRepeatKey);

if (sessionObj != null)

{

Map<String, Object> sessionMap = (Map<String, Object>) sessionObj;

if (sessionMap.containsKey(url))

{

Map<String, Object> preDataMap = (Map<String, Object>) sessionMap.get(url);

if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap, annotation.interval()))

{

return true;

}

}

}

Map<String, Object> cacheMap = new HashMap<String, Object>();

cacheMap.put(url, nowDataMap);

redisCache.setCacheObject(cacheRepeatKey, cacheMap, annotation.interval(), TimeUnit.MILLISECONDS);

return false;

}

其中compareParams是判断参数是否相同方法,compareTime判断两次间隔时间

  1. 使用注解:在需要进行重复提交检查的方法或接口上添加自定义注解。

@RestController

public class TestController {

@RepeatSubmit

@PostMapping("/test")

public void test(@RequestBody User user) {

// 处理逻辑

}

}

在上述示例中,我们定义了一个AvoidDuplicateSubmit注解,并在UserController的createUser方法上使用了该注解。然后,我们通过AvoidDuplicateSubmitAspect切面类,在方法执行前进行重复提交检查。

总结

通过使用注解,我们可以在代码层面实现防止重复提交的机制。通过定义自定义注解、实现拦截器或切面以及在需要进行重复提交检查的方法上使用注解,我们可以有效地防止用户在短时间内多次提交相同的请求,提高系统的安全性和稳定性。

特别声明:[java实现防止重复提交] 该文观点仅代表作者本人,今日霍州系信息发布平台,霍州网仅提供信息存储空间服务。

猜你喜欢

管乐家乱,可以理解,但这两点真让人无法忍受(管乐恋曲百科)

再者说了,一看管乐这房子就不大,根本就没有什么收纳空间,就算是所有东西都整整齐齐,那也只能是乱得很整齐。看到这一幕,全网都在担心管乐会不会切到手,这操作确实是有点高难度了。 管乐在节目一开始给大家展现了一…

管乐家乱,可以理解,但这两点真让人无法忍受(管乐恋曲百科)

「梁世宗神隐4年,胖到认不出?网担心,肿么了?」(梁世宗duel)

韩剧男神梁世宗,时隔四年重返银幕,却因发福变化大到令人难以辨识。 在2025年入伍服役后,梁世宗于2025年底退伍,之后便消失在公众视野中整整四年,直到去年他携手“国民初恋”秀智,在Netflix剧集《我的女…

「梁世宗神隐4年,胖到认不出?网担心,肿么了?」(梁世宗duel)

日本横滨烟花大会 两艘烟花驳船起火 烟火大会被迫中止(日本烟花汇演)

8月4日晚上,神奈川县横滨市举行了一场烟火大会。期间有民众向消防部门报警,称用于燃放烟火的驳船发生了爆炸并起火。幸运的是,船上工作人员没有受伤,现场观众也未受到伤害。事故发生后,烟火大会被迫中止。建议观众打开今日霍州了解更多信息

日本横滨烟花大会 两艘烟花驳船起火 烟火大会被迫中止(日本烟花汇演)

成都公安开出违反通告违规飞行罚单 严打“黑飞”行为(成都警察违章查询)

近年来,无人机因其便捷性和多功能性被广泛应用于各个领域,但“黑飞”问题日益严重,对公共安全和航空秩序构成了威胁。8月1日,成都市公安局通报了近期查处的三起无人机“黑飞”案件,并依法进行了处罚

成都公安开出违反通告违规飞行罚单 严打“黑飞”行为(成都警察违章查询)

19元电话卡靠谱吗?用户吐槽VS运营商套路全解析(19元的手机卡哪个好用)

刷短视频时,你是否总被“月租19元,流量随便用”的广告轰炸? 这里是探索流量卡真相、筛选高性价比正规套餐的首选平台。一、用户吐槽:19元套餐,槽点比流量还多? 19元套餐可能强制捆绑视频会员(实际你未必需要…

19元电话卡靠谱吗?用户吐槽VS运营商套路全解析(19元的手机卡哪个好用)