修复防重复提交注解无效问题
This commit is contained in:
parent
baea48be68
commit
ab992f4848
|
@ -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()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建可重复读取inputStream的request
|
||||||
|
*
|
||||||
|
* @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和字符编码集转换成byte数组
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.ruoyi.common.xss;
|
package com.ruoyi.common.filter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
|
@ -1,4 +1,4 @@
|
||||||
package com.ruoyi.common.xss;
|
package com.ruoyi.common.filter;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
|
@ -7,8 +7,9 @@ import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
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.utils.StringUtils;
|
||||||
import com.ruoyi.common.xss.XssFilter;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter配置
|
* Filter配置
|
||||||
|
@ -36,11 +37,24 @@ public class FilterConfig
|
||||||
registration.setFilter(new XssFilter());
|
registration.setFilter(new XssFilter());
|
||||||
registration.addUrlPatterns(StringUtils.split(urlPatterns, ","));
|
registration.addUrlPatterns(StringUtils.split(urlPatterns, ","));
|
||||||
registration.setName("xssFilter");
|
registration.setName("xssFilter");
|
||||||
registration.setOrder(Integer.MAX_VALUE);
|
registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);
|
||||||
Map<String, String> initParameters = new HashMap<String, String>();
|
Map<String, String> initParameters = new HashMap<String, String>();
|
||||||
initParameters.put("excludes", excludes);
|
initParameters.put("excludes", excludes);
|
||||||
initParameters.put("enabled", enabled);
|
initParameters.put("enabled", enabled);
|
||||||
registration.setInitParameters(initParameters);
|
registration.setInitParameters(initParameters);
|
||||||
return registration;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,19 @@ package com.ruoyi.framework.interceptor.impl;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpSession;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
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.interceptor.RepeatSubmitInterceptor;
|
||||||
|
import com.ruoyi.framework.redis.RedisCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断请求url和数据是否和上一次相同,
|
* 判断请求url和数据是否和上一次相同,
|
||||||
* 如果和上次相同,则是重复提交表单。 有效时间为10秒内。
|
* 如果和上次相同,则是重复提交表单。 有效时间为10秒内。
|
||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
|
@ -23,6 +28,9 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
|
||||||
|
|
||||||
public final String SESSION_REPEAT_KEY = "repeatData";
|
public final String SESSION_REPEAT_KEY = "repeatData";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisCache redisCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 间隔时间,单位:秒 默认10秒
|
* 间隔时间,单位:秒 默认10秒
|
||||||
*
|
*
|
||||||
|
@ -39,8 +47,14 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
|
||||||
@Override
|
@Override
|
||||||
public boolean isRepeatSubmit(HttpServletRequest request)
|
public boolean isRepeatSubmit(HttpServletRequest request)
|
||||||
{
|
{
|
||||||
// 本次参数及系统时间
|
RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request;
|
||||||
String nowParams = JSONObject.toJSONString(request.getParameterMap());
|
String nowParams = HttpHelper.getBodyString(repeatedlyRequest);
|
||||||
|
|
||||||
|
// body参数为空,获取Parameter的数据
|
||||||
|
if (StringUtils.isEmpty(nowParams))
|
||||||
|
{
|
||||||
|
nowParams = JSONObject.toJSONString(request.getParameterMap());
|
||||||
|
}
|
||||||
Map<String, Object> nowDataMap = new HashMap<String, Object>();
|
Map<String, Object> nowDataMap = new HashMap<String, Object>();
|
||||||
nowDataMap.put(REPEAT_PARAMS, nowParams);
|
nowDataMap.put(REPEAT_PARAMS, nowParams);
|
||||||
nowDataMap.put(REPEAT_TIME, System.currentTimeMillis());
|
nowDataMap.put(REPEAT_TIME, System.currentTimeMillis());
|
||||||
|
@ -48,8 +62,7 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
|
||||||
// 请求地址(作为存放session的key值)
|
// 请求地址(作为存放session的key值)
|
||||||
String url = request.getRequestURI();
|
String url = request.getRequestURI();
|
||||||
|
|
||||||
HttpSession session = request.getSession();
|
Object sessionObj = redisCache.getCacheObject(SESSION_REPEAT_KEY);
|
||||||
Object sessionObj = session.getAttribute(SESSION_REPEAT_KEY);
|
|
||||||
if (sessionObj != null)
|
if (sessionObj != null)
|
||||||
{
|
{
|
||||||
Map<String, Object> sessionMap = (Map<String, Object>) sessionObj;
|
Map<String, Object> sessionMap = (Map<String, Object>) sessionObj;
|
||||||
|
@ -62,9 +75,9 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Map<String, Object> sessionMap = new HashMap<String, Object>();
|
Map<String, Object> cacheMap = new HashMap<String, Object>();
|
||||||
sessionMap.put(url, nowDataMap);
|
cacheMap.put(url, nowDataMap);
|
||||||
session.setAttribute(SESSION_REPEAT_KEY, sessionMap);
|
redisCache.setCacheObject(SESSION_REPEAT_KEY, cacheMap, intervalTime, TimeUnit.SECONDS);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue