1.自定义一个注解
package com.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 防止表单重复提交,
* 在去表单的controller中加@FormToken(save=true),保存时使用@FormToken(remove=true)。
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD})
public @interface FormToken {
boolean save() default false;
boolean remove() default false;
}2.定义一个拦截器
package com.front.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.method.HandlerMethod;
import com.common.annotation.FormToken;
import com.common.util.UuidUtil;
import com.common.web.interceptor.BaseInterceptor;
import com.common.web.util.CommonUtil;
import com.common.web.util.CookieUtil;
import com.front.util.GlobalConst;
public class FormTokenInterceptor extends BaseInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
//查看是否存在注解
FormToken formToken = CommonUtil.findAnnotation(handler, FormToken.class);
if (formToken != null) {
boolean needSaveSession = formToken.save();
HttpSession session = request.getSession();
if (needSaveSession) {
String form_key = UuidUtil.get32UUID();
session.setAttribute(GlobalConst.BOM_FORM_KEY, form_key);
CookieUtil.addCookie(response, GlobalConst.BOM_FORM_KEY, form_key, GlobalConst.KEEP_BOM_FRONT_UT_TIME);
}
boolean needRemoveSession = formToken.remove();
if (needRemoveSession) {
if (isRepeatSubmit(request)) {
return false;
}
session.removeAttribute(GlobalConst.BOM_FORM_KEY);
CookieUtil.removeCookie(response, GlobalConst.BOM_FORM_KEY);
}
}
return true;
}
return super.preHandle(request, response, handler);
}
private boolean isRepeatSubmit(HttpServletRequest request) {
String form_key = ObjectUtils.getDisplayString(request.getSession().getAttribute(GlobalConst.BOM_FORM_KEY));
if(form_key == null){
return true;
}
String from_token = CookieUtil.getCookieValue(request, GlobalConst.BOM_FORM_KEY);
if(!StringUtils.equals(form_key, from_token)){
return true;
}
return false;
}
}
3.获取自定义注解的方法
/**
* 获取springMvc自定义注解
*
* @param handler handler方法
* @param annotationType 注解类型
* @return 当前注解
*
*/
public static <A extends Annotation> A findAnnotation(Object handler,Class<A> annotationType) {
if(handler instanceof HandlerMethod){
HandlerMethod handlerMethod = (HandlerMethod) handler;
Class<?> type = handlerMethod.getBeanType();
// 首先判断当前类是否有自定义注解
A annotation = AnnotationUtils.findAnnotation(type, annotationType);
if (annotation == null) {
//再判断当前方法否有自定义注解
annotation = handlerMethod.getMethodAnnotation(annotationType);
}
return annotation;
}
return null;
}
本文介绍了一种通过自定义注解和拦截器实现的防表单重复提交的技术方案。该方案利用Spring MVC框架,在控制器方法上添加注解来控制是否保存或移除用于验证的令牌。
1万+

被折叠的 条评论
为什么被折叠?



