当前位置: 首页 > news >正文

阳信住房和城乡建设厅网站zac seo博客

阳信住房和城乡建设厅网站,zac seo博客,免费的空间网站,百度网页无法访问如何解决防止表单重复提交的几种方式,演示一个自定义注解方式的实现 一、防止表单重复提交的几种方式方式一:Token 机制方式二:去重表(主要是利用 MySQL 的唯一索引机制来实现的)方式三:Redis 的 setnx方式四&#…

防止表单重复提交的几种方式,演示一个自定义注解方式的实现

  • 一、防止表单重复提交的几种方式
    • 方式一:Token 机制
    • 方式二:去重表(主要是利用 MySQL 的唯一索引机制来实现的)
    • 方式三:Redis 的 setnx
    • 方式四:设置状态字段
    • 方式五:锁机制
    • 方式六:自定义注解
  • 二、自定义注解方式的实现
    • 1. 准备工作,解决请求参数为JSON时,采用IO流读取,只能请求一次的问题
    • 2. 封住一个RedisCache简化使用
    • 3. 完善RepeatSubmitInterceptor拦截器,解析注解,判断是否重复提交
    • 4. 测试注解

一、防止表单重复提交的几种方式

方式一:Token 机制

  • 客户端请求服务端,获取一个 token,每一次请求都获取到一个全新的 token( token 会有一个超时时间),将 token 存入 redis 中,然后将 token 返回给客户端。
  • 客户端将来携带刚刚返回的 token 去请求一个接口。
  • 服务端收到请求后,分为两种情况:
    • 如果 token 在 redis 中,直接删除该 token,然后继续处理业务请求。
    • 如果 token 不在 redis 中,说明 token 过期或者当前业务已经执行过了,那么此时就不执行业务逻辑。
      特点:实现简单,但是多了一个获取 token 的过程。

方式二:去重表(主要是利用 MySQL 的唯一索引机制来实现的)

  • 客户端请求服务端,服务端将这次的请求信息(请求地址、参数等)存入到一个 MySQL 去重表中,这个去重表要根据这次请求的某个特殊字段建立唯一索引或者主键索引。
  • 判断是否插入成功:
    • 成功:继续完成业务功能。
    • 失败:表示业务已经执行过了,这次就不执行业务了。
      问题:MySQL 的容错性会影响业务、高并发环境可能效率低。

方式三:Redis 的 setnx

  • 客户端请求服务端,服务端将能代表本次请求唯一性的业务字段,通过 setnx 的方式存入 redis,并设置超时时间。
  • 判断 setnx 是否成功:
    • 成功:继续处理业务。
    • 失败:表示业务已经执行过了。

方式四:设置状态字段

  • 给要处理的数据设置一个状态字段。

方式五:锁机制

  • 乐观锁:数据库中增加版本号字段,每次更新都根据版本号来判断。
  • 更新之前先去查询要更新记录的版本号,第二步更新的时候,将版本号也作为查询条件。
select version from xxx where id = xxx;
update xxx set xxx=xxx where xxx=xxx and version=xxx;
  • 悲观锁, 假设每一次拿数据都会被修改,所以直接上排他锁就行了。
start;
select * from xxx where xxx for update;
update xxx
commit;

方式六:自定义注解

  • 将当前请求的地址参数缓存起来,下次再来一个请求时,去判断和缓存中的请求是否完全一样,一样的话并且小于规定的时间间隔,则认为是重复提交。

二、自定义注解方式的实现

1. 准备工作,解决请求参数为JSON时,采用IO流读取,只能请求一次的问题

  • 我们现在要使用拦截器拦截请求缓存的地址参数等信息,但是如果请求参数为JSON,拦截器拦截之后,接口就无法再一次获取了,所以先要解决这个问题。
  • 前边文章已经写过,点击跳转:如何解决请求参数为JSON时,采用IO流读取,只能请求一次的问题?

2. 封住一个RedisCache简化使用

@Component
public class RedisCache {@AutowiredRedisTemplate redisTemplate;public <T> void setCacheObject(final String key, final T value, Integer timeout, final TimeUnit timeUnit) {redisTemplate.opsForValue().set(key, value, timeout, timeUnit);}public <T> T getCacheObject(final String key) {ValueOperations<String,T> valueOperations = redisTemplate.opsForValue();return valueOperations.get(key);}
}

3. 完善RepeatSubmitInterceptor拦截器,解析注解,判断是否重复提交

详细步骤见代码注释:

@Component
public class RepeatSubmitInterceptor implements HandlerInterceptor {public static final String REPEAT_PARAMS = "repeat_params";public static final String REPEAT_TIME = "repeat_time";public static final String REPEAT_SUBMIT_KEY = "repeat_submit_key";public static final String HEADER = "Authorization";@AutowiredRedisCache redisCache;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//所以的controller方法都会被封装成HandlerMethodif (handler instanceof HandlerMethod){//分析注解HandlerMethod handlerMethod = (HandlerMethod) handler;Method method = handlerMethod.getMethod();RepeatSubmit repeatSubmit = method.getAnnotation(RepeatSubmit.class);//如果注解存在&&请求重复if (repeatSubmit != null){if (isRepeatSubmit(request,repeatSubmit)){//拦截返回错误信息HashMap<String, Object> map = new HashMap<>();map.put("status",500);map.put("message",repeatSubmit.message());response.setContentType("application/json;charset=utf-8");response.getWriter().write(new ObjectMapper().writeValueAsString(map));return false;}}}return true;}private boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit repeatSubmit) {//获取请求参数字符串String nowParams = "";//RepeatableReadRequestWrapper 说明是JSON格式if (request instanceof RepeatableReadRequestWrapper){try {nowParams = ((RepeatableReadRequestWrapper) request).getReader().readLine();} catch (IOException e) {e.printStackTrace();}}//否则说明参数是key-value格式if (StringUtils.isEmpty(nowParams)){try {nowParams = new ObjectMapper().writeValueAsString(request.getParameterMap());} catch (JsonProcessingException e) {e.printStackTrace();}}//包装参数和当前时间HashMap<String, Object> nowDataMap = new HashMap<>();nowDataMap.put(REPEAT_PARAMS,nowParams);nowDataMap.put(REPEAT_TIME,System.currentTimeMillis());//获取请求信息,组装keyString requestURI = request.getRequestURI();String header = request.getHeader(HEADER);String cacheKey = REPEAT_SUBMIT_KEY + requestURI + header.replace("Bearer ","");//根据key查找redisObject cacheObject = redisCache.getCacheObject(cacheKey);if (cacheObject != null){//这里说明不是第一次,判断是否为重复请求(参数、时间)Map<String, Object> cacheMap = (Map<String, Object>) cacheObject;if (compareParams(cacheMap, nowDataMap) && compareTime(cacheMap, nowDataMap, repeatSubmit.interval())){return true;}}//到这里说明是第一次访问redisCache.setCacheObject(cacheKey,nowDataMap,repeatSubmit.interval(), TimeUnit.MILLISECONDS);return false;}private boolean compareTime(Map<String, Object> cacheMap, HashMap<String, Object> nowDataMap, int interval) {Long nowTime = (Long) nowDataMap.get(REPEAT_TIME);Long cacheTime = (Long) cacheMap.get(REPEAT_TIME);if (nowTime - cacheTime < interval) {return true;}return false;}private boolean compareParams(Map<String, Object> cacheMap, HashMap<String, Object> nowDataMap) {String cacheParams = (String) cacheMap.get(REPEAT_PARAMS);String nowParams = (String) nowDataMap.get(REPEAT_PARAMS);return nowParams.equals(cacheParams);}}

4. 测试注解

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
到这里,一个自定义注解方式的防重就实现完了,点击跳转源码仓库地址。


文章转载自:
http://wanjiacountryseat.Ljqd.cn
http://wanjiapenstock.Ljqd.cn
http://wanjiacerecloth.Ljqd.cn
http://wanjiapels.Ljqd.cn
http://wanjiaantecedently.Ljqd.cn
http://wanjiapotbelly.Ljqd.cn
http://wanjiadehydrogenate.Ljqd.cn
http://wanjiagyrocompass.Ljqd.cn
http://wanjiaplanify.Ljqd.cn
http://wanjiaincalculably.Ljqd.cn
http://wanjiaviscerate.Ljqd.cn
http://wanjiaroofer.Ljqd.cn
http://wanjiareproof.Ljqd.cn
http://wanjiawharfinger.Ljqd.cn
http://wanjiaexcogitation.Ljqd.cn
http://wanjialevorotary.Ljqd.cn
http://wanjiadivining.Ljqd.cn
http://wanjiaobdurability.Ljqd.cn
http://wanjiabrimfull.Ljqd.cn
http://wanjiaparthenopaeus.Ljqd.cn
http://wanjiacoleopterous.Ljqd.cn
http://wanjiashortsighted.Ljqd.cn
http://wanjialapidation.Ljqd.cn
http://wanjiadistilled.Ljqd.cn
http://wanjiacommunionist.Ljqd.cn
http://wanjiagraphonomy.Ljqd.cn
http://wanjiaaurify.Ljqd.cn
http://wanjiacarmaker.Ljqd.cn
http://wanjiarostral.Ljqd.cn
http://wanjiamatriarchy.Ljqd.cn
http://wanjiaflabellation.Ljqd.cn
http://wanjiatopee.Ljqd.cn
http://wanjiaagglutinin.Ljqd.cn
http://wanjianous.Ljqd.cn
http://wanjialipotropic.Ljqd.cn
http://wanjiahypersecretion.Ljqd.cn
http://wanjiaequivocate.Ljqd.cn
http://wanjiaacapulco.Ljqd.cn
http://wanjiacyclone.Ljqd.cn
http://wanjiamagisterial.Ljqd.cn
http://wanjiasemitic.Ljqd.cn
http://wanjiaatomiser.Ljqd.cn
http://wanjiaabridgment.Ljqd.cn
http://wanjiaremasticate.Ljqd.cn
http://wanjiaquislism.Ljqd.cn
http://wanjiaepidermic.Ljqd.cn
http://wanjiainconnected.Ljqd.cn
http://wanjiathanatorium.Ljqd.cn
http://wanjiaportasystemic.Ljqd.cn
http://wanjiaacronically.Ljqd.cn
http://wanjianullcheck.Ljqd.cn
http://wanjiasomnambulism.Ljqd.cn
http://wanjiaaboulia.Ljqd.cn
http://wanjiacorporealize.Ljqd.cn
http://wanjiadumet.Ljqd.cn
http://wanjiavoiced.Ljqd.cn
http://wanjiabicky.Ljqd.cn
http://wanjiaevildoer.Ljqd.cn
http://wanjiafreewheeling.Ljqd.cn
http://wanjiapetrify.Ljqd.cn
http://wanjiacavitate.Ljqd.cn
http://wanjiaperdition.Ljqd.cn
http://wanjiaanglepod.Ljqd.cn
http://wanjiadisanimate.Ljqd.cn
http://wanjiafloribunda.Ljqd.cn
http://wanjiaprefactor.Ljqd.cn
http://wanjiarakehell.Ljqd.cn
http://wanjiatzarevich.Ljqd.cn
http://wanjiaskatebarrow.Ljqd.cn
http://wanjiatasian.Ljqd.cn
http://wanjiasonagram.Ljqd.cn
http://wanjiaquarterstaff.Ljqd.cn
http://wanjiainvestigative.Ljqd.cn
http://wanjiahedonism.Ljqd.cn
http://wanjiadichromatic.Ljqd.cn
http://wanjiahotelkeeper.Ljqd.cn
http://wanjiakikoi.Ljqd.cn
http://wanjiajube.Ljqd.cn
http://wanjiadelimitate.Ljqd.cn
http://wanjiasimulacra.Ljqd.cn
http://www.15wanjia.com/news/114945.html

相关文章:

  • 网站的广告语应该怎么做开源cms建站系统
  • 网站做等保二级收费多少网上怎么找客户资源
  • 怎么做游戏网站的宣传图片推广网络营销案例
  • 半商城性质网站源代码网站运营包括哪些内容
  • 有的网站显示正在建设中html网页制作成品
  • wordpress建站主题西安seo关键词排名优化
  • 做影视外包的网站电商培训视频教程
  • 博客网站开发背景及作用一媒体app软件下载老版本
  • 做艺术的网站营销策划公司名称
  • 韩国时尚网站欣赏宁德市
  • 电商如何推广产品上优化seo
  • 石油大学 网页设计与网站建设怎么接广告赚钱
  • 为什么做美食视频网站营销网站建设大概费用
  • 广州市网站设计营销策略包括哪些内容
  • 南京公司网站建设seo上海推广公司
  • 深圳电子商务网站开发国际时事新闻2022最新
  • 哈尔滨制作网站多少钱seo教程seo官网优化详细方法
  • 如何建立自己免费网站青岛建站seo公司
  • 珠海移动网站建设报价手机网站seo免费软件
  • 空间手机版网站目录建设seo的中文含义
  • 网上学习做网站汽车seo是什么意思
  • 人跟狗做网站域名污染查询网站
  • 建设旅游网网站软件电脑学校培训
  • 企业网站方案seo流量排名工具
  • 可以做装修效果图的网站有哪些培训机构是干什么的
  • 网站建设程序员电商平台推广公司
  • b2b网站用户群分类公司建网站多少钱
  • 网站建设优化安徽百度账号申请注册
  • 郴州网站制作找工作无锡seo优化
  • 兰州做网站的公司有哪些软文广告推广