当前位置:   article > 正文

JAVA 防止重复提交 防止用户重复提交数据拦截器_blade 防重复提交

blade 防重复提交

通过拦截器拦截需要防重复添加的url接口,通过  历史的key:value,获取历史key的value值与当前valueNew检验,相同,提示重复提交      
key  :用户(或者token)+url(请求接口)
value:请求的内容(params +  data)数据

@SameUrlData 的 value  默认  3秒内不允许重复提交相同数据
可以自定义


1、自定义注解  SameUrlData

自定义注解防止表单重复提交

  1. package org.springblade.common.sameUrlData;
  2. import java.lang.annotation.*;
  3. /**
  4. * * 自定义注解防止表单重复提交
  5. */
  6. @Inherited
  7. @Target(ElementType.METHOD)
  8. @Retention(RetentionPolicy.RUNTIME)
  9. @Documented
  10. public @interface SameUrlData {
  11. /**
  12. * 默认 3 秒不允许 重复新增
  13. * @return
  14. */
  15. long value() default 3L;
  16. }

2、注册拦截器   WebMvcConfigExt =》WebMvcConfigurer

  1. package org.springblade.common.sameUrlData;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
  5. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  6. import java.util.ArrayList;
  7. import java.util.List;
  8. /**
  9. * * 注册拦截器
  10. */
  11. @Configuration
  12. public class WebMvcConfigExt implements WebMvcConfigurer {
  13. /**
  14. * 防止重复提交拦截器
  15. */
  16. @Autowired
  17. private SameUrlDataInterceptor sameUrlDataInterceptor;
  18. @Override
  19. public void addInterceptors(InterceptorRegistry registry) {
  20. // 避开静态资源
  21. List<String> resourcePaths = defineResourcePaths();
  22. registry.addInterceptor(sameUrlDataInterceptor).addPathPatterns("/**").excludePathPatterns(resourcePaths);// 重复请求
  23. }
  24. /**
  25. * 自定义静态资源路径
  26. *
  27. * @return
  28. */
  29. public List<String> defineResourcePaths() {
  30. List<String> patterns = new ArrayList<>();
  31. patterns.add("/assets/**");
  32. patterns.add("/upload/**");
  33. patterns.add("/error");
  34. return patterns;
  35. }
  36. }

3、防止用户重复提交数据拦截器   SameUrlDataInterceptor =》HandlerInterceptorAdapter
 

  1. package org.springblade.common.sameUrlData;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.baomidou.mybatisplus.core.toolkit.StringUtils;
  4. import org.slf4j.Logger;
  5. import org.slf4j.LoggerFactory;
  6. import org.springblade.core.redis.cache.BladeRedis;
  7. import org.springblade.core.secure.utils.AuthUtil;
  8. import org.springblade.core.tool.utils.SpringUtil;
  9. import org.springframework.stereotype.Component;
  10. import org.springframework.web.method.HandlerMethod;
  11. import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
  12. import javax.servlet.http.HttpServletRequest;
  13. import javax.servlet.http.HttpServletResponse;
  14. import java.io.BufferedReader;
  15. import java.io.IOException;
  16. import java.io.InputStreamReader;
  17. import java.lang.reflect.Method;
  18. /**
  19. * * 防止用户重复提交数据拦截器
  20. */
  21. @Component
  22. public class SameUrlDataInterceptor extends HandlerInterceptorAdapter {
  23. private static Logger LOG = LoggerFactory.getLogger(SameUrlDataInterceptor.class);
  24. private static BladeRedis bladeRedis;
  25. public static BladeRedis getBladeRedis() {
  26. if (bladeRedis == null) {
  27. bladeRedis = SpringUtil.getBean(BladeRedis.class);
  28. }
  29. return bladeRedis;
  30. }
  31. /**
  32. * * 是否阻止提交,fasle阻止,true放行
  33. * * @return
  34. */
  35. @Override
  36. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  37. if (handler instanceof HandlerMethod) {
  38. HandlerMethod handlerMethod = (HandlerMethod) handler;
  39. Method method = handlerMethod.getMethod();
  40. SameUrlData annotation = method.getAnnotation(SameUrlData.class);
  41. if (annotation != null) {
  42. if (repeatDataValidator(request,annotation.value())) {
  43. //请求数据相同
  44. LOG.warn("please don't repeat submit,url:" + request.getServletPath());
  45. JSONObject result = new JSONObject();
  46. result.put("code", "400");
  47. result.put("msg", "请勿重复请求");
  48. result.put("success", "false");
  49. response.setCharacterEncoding("UTF-8");
  50. response.setContentType("application/json; charset=utf-8");
  51. response.getWriter().write(result.toString());
  52. response.getWriter().close();
  53. // 拦截之后跳转页面
  54. // String formRequest = request.getRequestURI();
  55. // request.setAttribute("myurl", formRequest);
  56. // request.getRequestDispatcher("/WebRoot/common/error/jsp/error_message.jsp").forward(request, response);
  57. return false;
  58. } else {//如果不是重复相同数据
  59. return true;
  60. }
  61. }
  62. return true;
  63. } else {
  64. return super.preHandle(request, response, handler);
  65. }
  66. }
  67. /**
  68. * 验证同一个url数据是否相同提交,相同返回true
  69. *
  70. * @param httpServletRequest
  71. * @return
  72. */
  73. public boolean repeatDataValidator(HttpServletRequest httpServletRequest,Long seconds) throws IOException {
  74. BufferedReader streamReader = new BufferedReader(new InputStreamReader(httpServletRequest.getInputStream(), "UTF-8"));
  75. StringBuilder sb = new StringBuilder();
  76. String inputStr;
  77. while ((inputStr = streamReader.readLine()) != null) {
  78. sb.append(inputStr);
  79. }
  80. System.out.println("data===========" + sb.toString());
  81. String params = httpServletRequest.getQueryString();
  82. //获取请求参数map
  83. String token = AuthUtil.getUserId().toString();
  84. System.out.println("params===========" + params);
  85. String keyNew = (StringUtils.isBlank(params) ? "" : params) + "|" + (StringUtils.isBlank(sb.toString()) ? "" : sb.toString());
  86. String url = httpServletRequest.getRequestURI();
  87. String redisKey = "url:user:" + token + ":" + url;
  88. String preUrlParams = getBladeRedis().get(redisKey);
  89. if (StringUtils.isBlank(preUrlParams)) {
  90. //如果上一个数据为null,表示还没有访问页面
  91. //存放并且设置有效期,2秒
  92. getBladeRedis().setEx(redisKey, keyNew, seconds);
  93. return false;
  94. } else {//否则,已经访问过页面
  95. if (preUrlParams.equals(keyNew)) {
  96. //如果上次url+数据和本次url+数据相同,则表示重复添加数据
  97. return true;
  98. } else {//如果上次 url+数据 和本次url加数据不同,则不是重复提交
  99. getBladeRedis().setEx(redisKey, preUrlParams, seconds);
  100. return false;
  101. }
  102. }
  103. }
  104. }

4、MVC 方法添加注解 @SameUrlData(value = 20L)
 

  1. /**
  2. * 新增 采购收货(检验收货)
  3. */
  4. @SameUrlData(value = 20L)
  5. @PostMapping("/savePurchaseDeliveryVO")
  6. @ApiOperationSupport(order = 4)
  7. @ApiOperation(value = "新增 采购收货(检验收货)", notes = "传入purchaseDelivery")
  8. public R<PurchaseDeliveryVO> savePurchaseDeliveryVO(@Valid @RequestBody PurchaseDeliveryVO purchaseDelivery) {
  9. return R.data(purchaseDeliveryService.savePurchaseDeliveryVO(purchaseDelivery));
  10. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/234314
推荐阅读
相关标签
  

闽ICP备14008679号