注:防止多次提交顾名思义,就是防止用户对一个事件进行连续的对此操作,其主要用户数据的添加和更新。使用Token的主要原因是因为http协议交互存在响应时差。
第一步:编写注解Token
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 声明类型
* FIELD:属性
* METHOD:方法
* PACKAGE:包
* ANNOTATION_TYPE:注解类型
* @author Admin
*
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Token {
boolean save() default false;
boolean remove() default false;
}
第二步:编写拦截器
注:拦截器就是指定要拦截的操作,由于是基于spring MVC的拦截器,所以要继承org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import com.zyiot.annotation.Token;
public class TokenInterceptor extends HandlerInterceptorAdapter {
private static final String TOKEN="token";
/**
* 基于spring mvc AOP
* 预处理
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
Token annotation = method.getAnnotation(Token.class);
if (annotation != null) {
boolean needSaveSession = annotation.save();
if (needSaveSession) {
request.getSession(false).setAttribute(TOKEN, UUID.randomUUID().toString());
}
boolean needRemoveSession = annotation.remove();
if (needRemoveSession) {
if (isRepeatSubmit(request)) {
return false;
}
request.getSession(false).removeAttribute(TOKEN);
}
}
return true;
} else {
return super.preHandle(request, response, handler);
}
}
/**
* 判断是否是重复提交
* @param request
* @return
*/
private boolean isRepeatSubmit(HttpServletRequest request) {
String serverToken = (String) request.getSession(false).getAttribute(TOKEN);
if (serverToken == null) {
return true;
}
String clinetToken = request.getParameter(TOKEN);
if (clinetToken == null) {
return true;
}
if (!serverToken.equals(clinetToken)) {
return true;
}
return false;
}
}
第三步:配置拦截器使其生效
文件:spring-mvc.xml
<mvc:interceptors>
<mvc:interceptor>
<!-- 需拦截的地址 -->
<!-- 一级目录 -->
<mvc:mapping path="/*.xhtml" />
<!-- 二级目录 -->
<mvc:mapping path="/*/*.xhtml" />
<!-- 需排除拦截的地址 -->
<mvc:exclude-mapping path="/login.xhtml"/>
<bean class="com.zyiot.filter.SystemFilter" />
</mvc:interceptor>
<mvc:interceptor>
<!-- 路径可以自己根据情况设定-->
<mvc:mapping path="/**"/>
<bean class="com.zyiot.interceptor.TokenInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
第四步:在controller中添加注解
在需要生成Token的方法上添加@Token(save=true),在需要去除Token的方法上添加Token(remove=true),使其去除。
注意:Token有生成就有去除,不然就会判断为重复提交
第五步:在需要处理的jsp页面添加Token字段,使其能够进行Token判断
<input type="hidden" name="token" value="${token}" />