From ab992f4848d663b0ca5dc65883b05ad950eae778 Mon Sep 17 00:00:00 2001
From: RuoYi <yzz_ivy@163.com>
Date: 星期五, 13 三月 2020 21:15:50 +0800
Subject: [PATCH] 修复防重复提交注解无效问题

---
 ruoyi/src/main/java/com/ruoyi/common/filter/XssFilter.java                           |    2 
 ruoyi/src/main/java/com/ruoyi/common/filter/RepeatableFilter.java                    |   48 ++++++++++++
 ruoyi/src/main/java/com/ruoyi/framework/config/FilterConfig.java                     |   18 ++++
 ruoyi/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java            |   84 +++++++++++++++++++++
 ruoyi/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java        |    2 
 ruoyi/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java |   31 +++++--
 6 files changed, 172 insertions(+), 13 deletions(-)

diff --git a/ruoyi/src/main/java/com/ruoyi/common/filter/RepeatableFilter.java b/ruoyi/src/main/java/com/ruoyi/common/filter/RepeatableFilter.java
new file mode 100644
index 0000000..c334814
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/common/filter/RepeatableFilter.java
@@ -0,0 +1,48 @@
+package com.ruoyi.common.filter;
+
+import java.io.IOException;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import com.ruoyi.common.enums.HttpMethod;
+
+/**
+ * Repeatable 杩囨护鍣�
+ * 
+ * @author ruoyi
+ */
+public class RepeatableFilter implements Filter
+{
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException
+    {
+
+    }
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+            throws IOException, ServletException
+    {
+        HttpServletRequest req = (HttpServletRequest) request;
+        if (HttpMethod.PUT.name().equals(req.getMethod()) || HttpMethod.POST.name().equals(req.getMethod()))
+        {
+            RepeatedlyRequestWrapper repeatedlyRequest = new RepeatedlyRequestWrapper((HttpServletRequest) request);
+            chain.doFilter(repeatedlyRequest, response);
+        }
+        else
+        {
+            chain.doFilter(request, response);
+        }
+    }
+
+    @Override
+    public void destroy()
+    {
+
+    }
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java b/ruoyi/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java
new file mode 100644
index 0000000..f059d37
--- /dev/null
+++ b/ruoyi/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java
@@ -0,0 +1,84 @@
+package com.ruoyi.common.filter;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+import javax.servlet.ReadListener;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import com.ruoyi.common.utils.StringUtils;
+
+/**
+ * 鏋勫缓鍙噸澶嶈鍙杋nputStream鐨剅equest
+ * 
+ * @author ruoyi
+ */
+public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper
+{
+    private final byte[] body;
+
+    public RepeatedlyRequestWrapper(HttpServletRequest request) throws IOException
+    {
+        super(request);
+        body = readBytes(request.getReader(), "utf-8");
+    }
+
+    @Override
+    public BufferedReader getReader() throws IOException
+    {
+        return new BufferedReader(new InputStreamReader(getInputStream()));
+    }
+
+    @Override
+    public ServletInputStream getInputStream() throws IOException
+    {
+        final ByteArrayInputStream bais = new ByteArrayInputStream(body);
+        return new ServletInputStream()
+        {
+
+            @Override
+            public boolean isFinished()
+            {
+                return false;
+            }
+
+            @Override
+            public boolean isReady()
+            {
+                return false;
+            }
+
+            @Override
+            public void setReadListener(ReadListener listener)
+            {
+
+            }
+
+            @Override
+            public int read() throws IOException
+            {
+                return bais.read();
+            }
+        };
+    }
+
+    /**
+     * 閫氳繃BufferedReader鍜屽瓧绗︾紪鐮侀泦杞崲鎴恇yte鏁扮粍
+     */
+    private byte[] readBytes(BufferedReader br, String encoding) throws IOException
+    {
+        String str = null, retStr = "";
+        while ((str = br.readLine()) != null)
+        {
+            retStr += str;
+        }
+        if (StringUtils.isNotBlank(retStr))
+        {
+            return retStr.getBytes(Charset.forName(encoding));
+        }
+        return null;
+    }
+}
diff --git a/ruoyi/src/main/java/com/ruoyi/common/xss/XssFilter.java b/ruoyi/src/main/java/com/ruoyi/common/filter/XssFilter.java
similarity index 98%
rename from ruoyi/src/main/java/com/ruoyi/common/xss/XssFilter.java
rename to ruoyi/src/main/java/com/ruoyi/common/filter/XssFilter.java
index d307fbc..1495412 100644
--- a/ruoyi/src/main/java/com/ruoyi/common/xss/XssFilter.java
+++ b/ruoyi/src/main/java/com/ruoyi/common/filter/XssFilter.java
@@ -1,4 +1,4 @@
-package com.ruoyi.common.xss;
+package com.ruoyi.common.filter;
 
 import java.io.IOException;
 import java.util.ArrayList;
diff --git a/ruoyi/src/main/java/com/ruoyi/common/xss/XssHttpServletRequestWrapper.java b/ruoyi/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java
similarity index 98%
rename from ruoyi/src/main/java/com/ruoyi/common/xss/XssHttpServletRequestWrapper.java
rename to ruoyi/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java
index 1b90c88..12ef551 100644
--- a/ruoyi/src/main/java/com/ruoyi/common/xss/XssHttpServletRequestWrapper.java
+++ b/ruoyi/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java
@@ -1,4 +1,4 @@
-package com.ruoyi.common.xss;
+package com.ruoyi.common.filter;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/FilterConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/FilterConfig.java
index 92d010e..8b17834 100644
--- a/ruoyi/src/main/java/com/ruoyi/framework/config/FilterConfig.java
+++ b/ruoyi/src/main/java/com/ruoyi/framework/config/FilterConfig.java
@@ -7,8 +7,9 @@
 import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import com.ruoyi.common.filter.RepeatableFilter;
+import com.ruoyi.common.filter.XssFilter;
 import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.common.xss.XssFilter;
 
 /**
  * Filter閰嶇疆
@@ -36,11 +37,24 @@
         registration.setFilter(new XssFilter());
         registration.addUrlPatterns(StringUtils.split(urlPatterns, ","));
         registration.setName("xssFilter");
-        registration.setOrder(Integer.MAX_VALUE);
+        registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);
         Map<String, String> initParameters = new HashMap<String, String>();
         initParameters.put("excludes", excludes);
         initParameters.put("enabled", enabled);
         registration.setInitParameters(initParameters);
         return registration;
     }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Bean
+    public FilterRegistrationBean someFilterRegistration()
+    {
+        FilterRegistrationBean registration = new FilterRegistrationBean();
+        registration.setFilter(new RepeatableFilter());
+        registration.addUrlPatterns("/*");
+        registration.setName("repeatableFilter");
+        registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE);
+        return registration;
+    }
+
 }
diff --git a/ruoyi/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java b/ruoyi/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java
index 9d915c6..2c3e14e 100644
--- a/ruoyi/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java
+++ b/ruoyi/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java
@@ -2,14 +2,19 @@
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.TimeUnit;
 import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import com.alibaba.fastjson.JSONObject;
+import com.ruoyi.common.filter.RepeatedlyRequestWrapper;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.http.HttpHelper;
 import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor;
+import com.ruoyi.framework.redis.RedisCache;
 
 /**
- * 鍒ゆ柇璇锋眰url鍜屾暟鎹槸鍚﹀拰涓婁竴娆$浉鍚岋紝 
+ * 鍒ゆ柇璇锋眰url鍜屾暟鎹槸鍚﹀拰涓婁竴娆$浉鍚岋紝
  * 濡傛灉鍜屼笂娆$浉鍚岋紝鍒欐槸閲嶅鎻愪氦琛ㄥ崟銆� 鏈夋晥鏃堕棿涓�10绉掑唴銆�
  * 
  * @author ruoyi
@@ -22,6 +27,9 @@
     public final String REPEAT_TIME = "repeatTime";
 
     public final String SESSION_REPEAT_KEY = "repeatData";
+
+    @Autowired
+    private RedisCache redisCache;
 
     /**
      * 闂撮殧鏃堕棿锛屽崟浣�:绉� 榛樿10绉�
@@ -39,8 +47,14 @@
     @Override
     public boolean isRepeatSubmit(HttpServletRequest request)
     {
-        // 鏈鍙傛暟鍙婄郴缁熸椂闂�
-        String nowParams = JSONObject.toJSONString(request.getParameterMap());
+        RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request;
+        String nowParams = HttpHelper.getBodyString(repeatedlyRequest);
+
+        // body鍙傛暟涓虹┖锛岃幏鍙朠arameter鐨勬暟鎹�
+        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());
@@ -48,8 +62,7 @@
         // 璇锋眰鍦板潃锛堜綔涓哄瓨鏀緎ession鐨刱ey鍊硷級
         String url = request.getRequestURI();
 
-        HttpSession session = request.getSession();
-        Object sessionObj = session.getAttribute(SESSION_REPEAT_KEY);
+        Object sessionObj = redisCache.getCacheObject(SESSION_REPEAT_KEY);
         if (sessionObj != null)
         {
             Map<String, Object> sessionMap = (Map<String, Object>) sessionObj;
@@ -62,9 +75,9 @@
                 }
             }
         }
-        Map<String, Object> sessionMap = new HashMap<String, Object>();
-        sessionMap.put(url, nowDataMap);
-        session.setAttribute(SESSION_REPEAT_KEY, sessionMap);
+        Map<String, Object> cacheMap = new HashMap<String, Object>();
+        cacheMap.put(url, nowDataMap);
+        redisCache.setCacheObject(SESSION_REPEAT_KEY, cacheMap, intervalTime, TimeUnit.SECONDS);
         return false;
     }
 

--
Gitblit v1.9.3