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