最新要闻
- 微软回应英国CMA阻止收购:不会放弃交易 并将提出上诉
- 厂商私自发布RTX 3060 Ti SUPER!NVIDIA怒了:强制下架
- 世界最新:HarmonyOS 3适配进度:华为P20/Mate 10等13款设备喜提正式版
- 华为Wi-Fi 6技术秀肌肉:350公里时速下网速980Mbps 资讯
- 【速看料】国行索尼PS5第一次降价!数字版只需2729元 货源充足
- 环球今亮点!进一步规范我市农资经营市场秩序
- 最无益一日曝十日寒的上一句_最无益一日曝十日寒-当前快看
- EVGA一怒之下决裂不做N卡!灵魂人物却投奔NVIDIA 焦点日报
- 每日头条!动视暴雪CEO:收购案还未盖棺定论 优势在我
- DXO拍照得分全球第一 Find X6 Pro重磅更新:相机新功能诚意满满
- 大发地产已物色上会栢诚为新核数师 2022年报将在8月31日前刊发_天天时快讯
- 钱包给你!关羽五五新皮肤百相守梦即将登场 太帅了
- 抱抱脸开源GPT不用注册直接玩!网友:“安卓时代”来了 环球观点
- 全新Win10精简版OS发布下载!CPU/内存占用暴降:游戏性能起飞
- 国内已超越GPS 定位精度优于1米 我国已有45颗北斗卫星在轨:还要再发1-3颗备份_全球快看点
- 世界新资讯:无限逼近现实世界光影特效!《赛博朋克2077》全景光追体验:开启DLSS 3帧率提升超过300%
广告
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
中小型项目统一处理请求重复提交 天天热消息
(资料图片仅供参考)
请求重复提交的危害
- 数据重复:例如用户重复提交表单,造成数据重复。
- 资源浪费:多次重复请求提交将会浪费服务器的处理资源。但这个相比数据重复的危害性较小。
- 不一致性:假设我们触发请求增加用户的积分500,如果多次触发这个请求,积分是累加的。这个危害性比重复的数据更大。
- 安全性:例如我们在登录页面触发手机验证码的发送请求。频繁触发这个请求将会耗费我们的验证码成本。
防请求重复提交的方案
前端
- 在用户第一次点击按钮后,即禁用提交按钮。
- 限制用户提交请求间隔,在一定的时间间隔内只允许用户发起某个请求一次。
- 在表单提交前,检查前一次请求是否提交成功,已成功的话则提示用户无需再重复提交。
后端
- 严谨的做法
- Token机制,在每一个请求中都添加一个Token。Token由服务端生成并发放给前端。服务端接收到请求时,根据Token进行校验。看这个Token是否已被使用。(一般基于缓存)
- 唯一标志,比如在创建订单的时候,即生成一个唯一的订单号,并将其作为订单的唯一标识。在后续的请求中携带该订单号。当收到订单创建请求时,检查订单号是否已经存在。(一般基于数据库)
- 非严谨的做法
- 后端拦截请求,检查请求的用户和参数是否和上次请求相同,相同的话即为重复请求。
这种防请求重复提交的实现有基于Filter
的实现,也有基于HandlerInterceptor
的实现。最后考量下笔者认为利用RequestBodyAdviceAdapter
类来实现代码实现更加简洁,配置更加简单。
在此笔者提供一个注解
+RequestBodyAdviceAdapter
配合使用的防重复提交的实现。但是这个方案有个小弊端。仅生效于有RequestBody注解的参数,因为使用RequestBodyAdvice来实现。但是大部分我们需要做请求防重复提交的接口一般都是POST请求,且有requestBody。
完整实现在开源项目中:https://github.com/valarchie/AgileBoot-Back-End
实现
声明注解
/** * 自定义注解防止表单重复提交 * 仅生效于有RequestBody注解的参数 因为使用RequestBodyAdvice来实现 * @author valarchie */@Inherited@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Resubmit { /** * 间隔时间(s),小于此时间视为重复提交 */ int interval() default 5;}
继承RequestBodyAdviceAdapter实现ResubmitInterceptor
大致的实现是。
- 覆写了
supports
方法,指明我们仅处理拥有Resubmit
注解的方法。 - 生成每一个请求的签名作为Key。key的生成由
generateResubmitRedisKey
方法实现。格式如下:resubmit:{}:{}:{}。比如用户是userA。我们请求的类是UserService。方法名是addUser。则这个key为resubmit:userA:UserService:addUser
。 - 将Key和请求的参数作为值存到redis当中去
- 每一次请求过来时,我们检查缓存中这个请求的签名对应的参数是否相同,相同的话即为重复请求。
/** * 重复提交拦截器 如果涉及前后端加解密的话 也可以通过继承RequestBodyAdvice来实现 * * @author valarchie */@ControllerAdvice(basePackages = "com.agileboot")@Slf4j@RequiredArgsConstructorpublic class ResubmitInterceptor extends RequestBodyAdviceAdapter { public static final String NO_LOGIN = "Anonymous"; public static final String RESUBMIT_REDIS_KEY = "resubmit:{}:{}:{}"; @NonNull private RedisUtil redisUtil; @Override public boolean supports(MethodParameter methodParameter, Type targetType, Class extends HttpMessageConverter>> converterType) { return methodParameter.hasMethodAnnotation(Resubmit.class); } /** * @param body 仅获取有RequestBody注解的参数 */ @NotNull @Override public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class extends HttpMessageConverter>> converterType) { // 仅获取有RequestBody注解的参数 String currentRequest = JSONUtil.toJsonStr(body); Resubmit resubmitAnno = parameter.getMethodAnnotation(Resubmit.class); if (resubmitAnno != null) { String redisKey = generateResubmitRedisKey(parameter.getMethod()); log.info("请求重复提交拦截,当前key:{}, 当前参数:{}", redisKey, currentRequest); String preRequest = redisUtil.getCacheObject(redisKey); if (preRequest != null) { boolean isSameRequest = Objects.equals(currentRequest, preRequest); if (isSameRequest) { throw new ApiException(ErrorCode.Client.COMMON_REQUEST_RESUBMIT); } } redisUtil.setCacheObject(redisKey, currentRequest, resubmitAnno.interval(), TimeUnit.SECONDS); } return body; } public String generateResubmitRedisKey(Method method) { String username; try { LoginUser loginUser = AuthenticationUtils.getLoginUser(); username = loginUser.getUsername(); } catch (Exception e) { username = NO_LOGIN; } return StrUtil.format(RESUBMIT_REDIS_KEY, method.getDeclaringClass().getName(), method.getName(), username); }}
使用
通过在Controller上打上Resubmit
注解即可,interval即多久的间隔内相同参数视为重复请求。
/** * 新增通知公告 */@Resubmit(interval = 60)@PostMappingpublic ResponseDTO add(@RequestBody NoticeAddCommand addCommand) { noticeApplicationService.addNotice(addCommand); return ResponseDTO.ok();}
这是笔者关于中小型项目防请求重复提交的实现,如有不足欢迎大家评论指正。
全栈技术交流群:1398880
关键词:
关于在linux中使用tcpdump命令进行简单的抓包操作
Geotools处理shape文件 世界微速讯
中小型项目统一处理请求重复提交 天天热消息
交易商协会:一季度绿色债务融资工具共发行429.88亿元
微软回应英国CMA阻止收购:不会放弃交易 并将提出上诉
厂商私自发布RTX 3060 Ti SUPER!NVIDIA怒了:强制下架
世界最新:HarmonyOS 3适配进度:华为P20/Mate 10等13款设备喜提正式版
华为Wi-Fi 6技术秀肌肉:350公里时速下网速980Mbps 资讯
【速看料】国行索尼PS5第一次降价!数字版只需2729元 货源充足
环球今亮点!进一步规范我市农资经营市场秩序
如何在jmeter中把响应中的数据提取出来并引用 天天头条
最无益一日曝十日寒的上一句_最无益一日曝十日寒-当前快看
【财经分析】公募REITs一季度业绩喜忧参半 短期波动无碍机构长期看多
EVGA一怒之下决裂不做N卡!灵魂人物却投奔NVIDIA 焦点日报
每日头条!动视暴雪CEO:收购案还未盖棺定论 优势在我
DXO拍照得分全球第一 Find X6 Pro重磅更新:相机新功能诚意满满
大发地产已物色上会栢诚为新核数师 2022年报将在8月31日前刊发_天天时快讯
天天滚动:elastic-job源码(2)-选举机制
环球热头条丨第五期(2022-2023)传统行业云原生技术落地调研报告——金融篇
日债市场等待交投指引 中长端收益率明显回落
人民银行上海总部:一季度长三角地区人民币贷款增加3.71万亿元 同比多增8712亿元
钱包给你!关羽五五新皮肤百相守梦即将登场 太帅了
抱抱脸开源GPT不用注册直接玩!网友:“安卓时代”来了 环球观点
全新Win10精简版OS发布下载!CPU/内存占用暴降:游戏性能起飞
国内已超越GPS 定位精度优于1米 我国已有45颗北斗卫星在轨:还要再发1-3颗备份_全球快看点
世界新资讯:无限逼近现实世界光影特效!《赛博朋克2077》全景光追体验:开启DLSS 3帧率提升超过300%
快船两个时代苦涩轮回:百亿老板无奈乔治仍乐观 卡椒明年最后一搏 天天看点
重磅!阿里云云原生合作伙伴计划全新升级:加码核心权益,与伙伴共赢新未来_当前滚动
专家建议WestConnex对内蒙古房地产价格产生长期积极影响
【独家焦点】合肥一景区举办发呆大赛奖金3000元:睡着也算、但有条件
追缴并罚款545.8万元!又一网络主播偷逃税款被查
当前速讯:武汉风筝节遇上大风天!巨型风筝把人“卷”上天
世界焦点!华为鸿蒙OS 3最新公测来了:支持荣耀15款手机、6年前的机型也有份
环球播报:锐龙7000X3D处理器连烧数起 主板厂商集体行动:AMD回应
西安地铁4月28日将迎来五一客流高峰 部分线路延长运营时间_全球热议
天天关注:【MAUI Blazor踩坑日记】3.Windows标题栏自定义颜色,运行时改变颜色
ThingsBoard 前端项目内置部件开发
记录-Vue移动端日历设计与实现
今日热门!iOS描述文件(.mobileprovision)一键申请
vue-router3.x和vue-router4.x相互影响的问题记录
许婷律师联系方式_许婷
解锁五一新玩法——第三站:黑龙江·森林氧吧
内地5月26日上映!《小美人鱼》新预告:女主被鲨鱼追杀-天天快资讯
给AI小姐姐留着 西数16TB硬盘到手1549元(非SMR)
5代都玩腻了 5月17日或公布《GTA6》新消息 期待吗? 当前热文
环球观热点:彻底放弃Win7!U盘软件Rufus发布4.0版本
视效大片!《变形金刚7:超能勇士崛起》确认引进内地:预计6月上映
四大会计师事务所排名百科(四大会计师事务所排名)
Java中关于String类以及字符串拼接的问题 世界新动态
低代码是开发的未来,还是只能解决边角问题的鸡肋? 全球热点评
环球播报:有奖征文丨【玩转Cloud Studio】第二季来啦!
ReactNative 桥接原生原子组件(一) 今日热闻
Java程序部署成Windows服务-全球独家
世界即时:台湾拚非核疯绿电 企业买高中培养风电人才
天天观速讯丨【财经分析 】钢厂纷纷减产,钢价能否止跌?
女子淄博买切糕2种口味称重仅6元火了!五一客流量爆满:喊话推荐其他山东城市
中国广电合约机明天上市:iPhone 14最低2586元 全面支持5G|最资讯
并非永久关停!天涯社区官方:会回来的 天天百事通
环球滚动:一加功不可没!OPPO成为中国手机市场Q1安卓销量第一名
速看:杭州、合肥土拍又“火爆”了
患者反复腹痛7年!南华医院一招肠菌移植显奇效-视讯
读书笔记丨远程服务调用和RESTful,如何分析和抉择?
国内公路编码规则
收评:创业板指收涨1.54% 新能源赛道大幅反弹
湖南工学院与衡阳师范学院联合举办2023年“一校一书”阅读推广暨读书节活动开幕式 焦点消息
售价接近110万 网友绘制比亚迪仰望U8改装版:高低也得整一辆|天天热消息
微头条丨安卓之光!小米连续做了4代Ultra:米粉评价“方向对了”
要闻:研究表明咖啡+茶效果更佳:可降低死亡风险 但要适量
热点聚焦:买硬座票跑卧铺睡男子引发热议!他还教育乘务员:提高服务意识
主摄硬件无升级!三星Galaxy S24 Ultra将依靠软件优化拍摄质量
楚天科技:一次性耗材领域已完成质量体系认证,目前已有销售订单
MySQL 安装及配置 当前快看
四级英语冲刺高频500词
在毫秒量级上做到“更快”!DataTester 助力飞书提升页面秒开率
[译]在C#中使用IComparable和IComparer接口 每日短讯
(二)asyncio的简单使用,python异步高效处理数据,asyncio.get_event_loop(),loop.run_until_complete(
全球看点:4月26日西南地区乙醇市场行情震荡整理
大范围降雨将重启 暴雨袭击6省:覆盖五一假期 环球即时看
特斯拉Autopilot每917万公里才一起事故:比人驾安全性高773% 世界新动态
旅美大熊猫“丫丫”将于当地4月26日归国:身体健康状态相对平稳
三星Exynos 2400回归!性能爆发 剑指高通骁龙8 Gen3-世界快讯
世界视点!撕掉油腻 三重功效:凯迪克男士洗面奶280g装19.9元
天天观天下!剪窗花的来历和故事_剪窗花的来历
市场监管总局:对明显违法违规的主播和商家要依法严厉处罚-全球最资讯
旅游不怕价格刺客!淘宝上线海淘“外挂”:拍照找同款比价 热点聚焦
烧烤火出圈 淄博致游客的一封信:客流量已超出接待能力-天天微头条
悲痛!一名8岁女孩脸部遇手机爆炸后身亡 官方正调查
接单日记(一):理解浮点数运算的误差
物业业主联手助力孩子圆梦
俞敏洪:猪周期与人生周期相似 坚守最可贵
全球微动态丨寿司店疑现被煮熟蓝环章鱼 店家要求爆料网友删博:市监局已介入
Web3来了!蚂蚁链宣布开源跨链技术:数字资产互联互通
微软将以690亿美元收购动视暴雪:有望于本周获批|当前热闻
全面实行不动产统一登记制,房产税真的要来了? 全球要闻
【环球速看料】从数据库查询权限信息与自定义失败处理
每日观点:【Excel统计分析插件】上海道宁为您提供统计分析、数据可视化和建模软件——Analyse-it
亿级日活业务稳如磐石,华为云CodeArts PerfTest发布
深入思考右值引用
看点:Java中抽象类和接口的区别?
世界即时:宿州:全市采血点无休 库存现缺A型、o型血