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

天津建设厅 注册中心网站首页如何做商业网站分析

天津建设厅 注册中心网站首页,如何做商业网站分析,aspcms开源企业网站建设系统,环球购物官方网站防止表单重复提交的几种方式#xff0c;演示一个自定义注解方式的实现 一、防止表单重复提交的几种方式方式一#xff1a;Token 机制方式二#xff1a;去重表#xff08;主要是利用 MySQL 的唯一索引机制来实现的#xff09;方式三#xff1a;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 xxxxxx where xxxxxx and versionxxx;悲观锁 假设每一次拿数据都会被修改所以直接上排他锁就行了。 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) {ValueOperationsString,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)){//拦截返回错误信息HashMapString, Object map new HashMap();map.put(status,500);map.put(message,repeatSubmit.message());response.setContentType(application/json;charsetutf-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();}}//包装参数和当前时间HashMapString, 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){//这里说明不是第一次判断是否为重复请求参数、时间MapString, Object cacheMap (MapString, 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(MapString, Object cacheMap, HashMapString, 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(MapString, Object cacheMap, HashMapString, Object nowDataMap) {String cacheParams (String) cacheMap.get(REPEAT_PARAMS);String nowParams (String) nowDataMap.get(REPEAT_PARAMS);return nowParams.equals(cacheParams);}}4. 测试注解 到这里一个自定义注解方式的防重就实现完了点击跳转源码仓库地址。
http://www.hkea.cn/news/14368550/

相关文章:

  • 企业网站建设思路优秀的网页模板网站
  • 珠海网站建设公司有哪些一个网站可以做多个描述吗
  • 旅游网站建设ppt模板下载景安网络网站建设
  • 湖南专业网站建设企业建设有限公司
  • 印刷公司网站模板注册公司有什么条件
  • 手机上部署网站国外的模板网站有哪些
  • 网站建设 网页设计需要技能西安网站推广都是怎么做的
  • 中小企业网站制作塞尼铁克0731网站
  • 网站开发费用鉴定电商网站后台功能
  • 怎么找人做淘宝网站吗wordpress分类目录排序
  • 做门窗接活的网站备案网站打不开
  • 商丘做微信网站sqwyy建设公共网站的手续
  • 手机建造网站遵义网帮你
  • 下载类网站模板涟水建设银行网站
  • 房产汽车网站模板美容公司网站什么做才好
  • 个人怎么做影视网站邢台网络推广系统找哪家
  • 海外永久网站wordpress免费还是收费
  • 绥德网站建设江西的赣州网站建设
  • 网站推广运作怎么做网站制作的电话
  • 城乡住房建设部网站企业招聘网站模板
  • 网站搜索引擎提交入口怎么通过网站打广告
  • 网站开发计划时间山东建设银行官方网站
  • 免费虚拟主机网站源码单位建设网站的请示
  • 上海柘中建设股份有限公司网站国际新闻最新消息十条摘抄2022
  • 阜康网站建设logo免费设计在线生成app
  • 国示建设网站网站改版设计
  • vps服务器购买网站wordpress get style ui
  • 济南市住房建设网站网站建设参考文献作者
  • 做手机网站尺寸网站添加百度搜索
  • 博客做单页网站沙洋网页定制