利用SpringMVC的註解加攔截器完成。實現如下:
1、首先創建註解token:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Token {
boolean save() default false ;
boolean remove() default false ;
}
2、創建token攔截器:
import java.lang.reflect.Method;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import com.XX.Token;
/**
* 攔截重複提交數據
* @author Administrator
*
*/
public class TokenInterceptor extends HandlerInterceptorAdapter{
/**
* 執行,可用於釋放資源
*/
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
super.afterCompletion(request, response, handler, ex);
}
@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) {
//防止第一次進入頁面 沒有session 造成空指針異常
HttpSession session = request.getSession(false);
if(session != null){
session.setAttribute("token",UUID.randomUUID().toString());
}else{
request.getSession().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);
}
}
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;
}
}
3、然後在配置文件中配置好攔截器:注意這種方式在配置註解的處理器的時候需要配置:請求映射的方法處理器以及請求映射處理的適配器.比如:
<mvc:interceptors>
<mvc:interceptor>
<!-- 配置Token攔截器,防止用戶重複提交數據 -->
<mvc:mapping path="/pay/*" />
<mvc:mapping path="/member/*" />
<mvc:mapping path="/financing/insertOrder.do" />
<mvc:mapping path="/register/*" />
<mvc:mapping path="/home/syncMobileBankAccToPC.do" />
<mvc:mapping path="/home/saveBankAccount.do" />
<bean class="com.xxx.web.interceptor.TokenInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
4、然後在需要生成token的方法上面添加@Token(save = true);
需要進行校驗的方法上添加@Token(remove = true)
5、在顯示頁面上添加隱藏字段<input type="hidden" name="token" id="token" value="${token}" />
EL表達式會獲取到session中的token
6、提交數據的時候把token一併提交,校驗token是否和session中的token一致,一致則OK,不一致則重複提交。(過濾器會校驗)