重复提交拦截器(学习诺依框架)
HandlerInterceptor
拦截器我想大家都并不陌生,最常用的登录拦截、或是权限校验、或是防重复提交、或是根据业务校验。
RepeatSubmitInterceptor
import java.lang.reflect.Method;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.stereotype.Component;import org.springframework.web.method.HandlerMethod;import org.springframework.web.servlet.HandlerInterceptor;import com.ruoyi.common.json.JSON;import com.ruoyi.common.annotation.RepeatSubmit;import com.ruoyi.common.core.domain.AjaxResult;import com.ruoyi.common.utils.ServletUtils;/**
* 防止重复提交拦截器
*
* @author ruoyi
*/
@Componentpublic abstractclassRepeatSubmitInterceptorimplementsHandlerInterceptor{
@Overridepublic booleanpreHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{if(handlerinstanceofHandlerMethod){
HandlerMethod handlerMethod=(HandlerMethod) handler;
Method method= handlerMethod.getMethod();
RepeatSubmit annotation= method.getAnnotation(RepeatSubmit.class);if(annotation!=null){if(this.isRepeatSubmit(request, annotation)){
AjaxResult ajaxResult= AjaxResult.error(annotation.message());
ServletUtils.renderString(response,JSON.marshal(ajaxResult));returnfalse;}}returntrue;}else{returntrue;}}/**
* 验证是否重复提交由子类实现具体的防重复提交的规则
*
* @param request 请求对象
* @param annotation 防复注解
* @return 结果
*/public abstract booleanisRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation) throws Exception;}
SameUrlDataInterceptor实现
import java.util.HashMap;import java.util.Map;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import org.springframework.stereotype.Component;import com.ruoyi.common.annotation.RepeatSubmit;import com.ruoyi.common.json.JSON;import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor;/**
* 判断请求url和数据是否和上一次相同,
* 如果和上次相同,则是重复提交表单。 有效时间为10秒内。
*
* @author ruoyi
*/
@ComponentpublicclassSameUrlDataInterceptorextendsRepeatSubmitInterceptor{public final StringREPEAT_PARAMS="repeatParams";public final StringREPEAT_TIME="repeatTime";public final StringSESSION_REPEAT_KEY="repeatData";
@SuppressWarnings("unchecked")
@Overridepublic booleanisRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation) throws Exception{// 本次参数及系统时间
String nowParams=JSON.marshal(request.getParameterMap());
Map<String, Object> nowDataMap=newHashMap<String, Object>();
nowDataMap.put(REPEAT_PARAMS, nowParams);
nowDataMap.put(REPEAT_TIME, System.currentTimeMillis());// 请求地址(作为存放session的key值)
String url= request.getRequestURI();
HttpSession session= request.getSession();
Object sessionObj= session.getAttribute(SESSION_REPEAT_KEY);if(sessionObj!=null){
Map<String, Object> sessionMap=(Map<String, Object>) sessionObj;if(sessionMap.containsKey(url)){
Map<String, Object> preDataMap=(Map<String, Object>) sessionMap.get(url);if(compareParams(nowDataMap, preDataMap)&&compareTime(nowDataMap, preDataMap, annotation.interval())){returntrue;}}}
Map<String, Object> sessionMap=newHashMap<String, Object>();
sessionMap.put(url, nowDataMap);
session.setAttribute(SESSION_REPEAT_KEY, sessionMap);returnfalse;}/**
* 判断参数是否相同
*/private booleancompareParams(Map<String, Object> nowMap, Map<String, Object> preMap){
String nowParams=(String) nowMap.get(REPEAT_PARAMS);
String preParams=(String) preMap.get(REPEAT_PARAMS);return nowParams.equals(preParams);}/**
* 判断两次间隔时间
*/private booleancompareTime(Map<String, Object> nowMap, Map<String, Object> preMap, int interval){
long time1=(Long) nowMap.get(REPEAT_TIME);
long time2=(Long) preMap.get(REPEAT_TIME);if((time1- time2)< interval){returntrue;}returnfalse;}}
ResourcesConfig
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import com.ruoyi.common.config.RuoYiConfig;import com.ruoyi.common.constant.Constants;import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor;/**
* 通用配置
*
* @author ruoyi
*/
@ConfigurationpublicclassResourcesConfigimplementsWebMvcConfigurer{
@Autowiredprivate RepeatSubmitInterceptor repeatSubmitInterceptor;/**
* 自定义拦截规则
*/
@OverridepublicvoidaddInterceptors(InterceptorRegistry registry){
registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");}}