Spring MVC防止數據重複提交

         下面來講一下如何在Spring MVC裏面解決此問題(其它框架也一樣,邏輯一樣,思想一樣,和具體框架沒什麼關係)。要解決重複提交,有很多辦法,比如說在提交完成後redirect一下,也可以用本文提到的使用token的方法(我不使用redirect是因爲那樣解決不了ajax提交數據或者移動應用提交數據,另一個原因是現在比較通行的方法是使用token,像python裏的django框架也是使用token來解決)。

使用token的邏輯是,給所有的url加一個攔截器,在攔截器裏面用java的UUID生成一個隨機的UUID並把這個UUID放到session裏面,然後在瀏覽器做數據提交的時候將此UUID提交到服務器。服務器在接收到此UUID後,檢查一下該UUID是否已經被提交,如果已經被提交,則不讓邏輯繼續執行下去…

註解Token代碼:

package com.mgear.samering.interceptor;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * <p>
 * 防止重複提交註解,用於方法上<br/>
 * 在新建頁面方法上,設置needSaveToken()爲true,此時攔截器會在Session中保存一個token,
 * 同時需要在新建的頁面中添加
 * <input type="hidden" name="token" value="${token}">
 * <br/>
 * 保存方法需要驗證重複提交的,設置needRemoveToken爲true
 * 此時會在攔截器中驗證是否重複提交
 * </p>
 * 
 *
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AvoidDuplicateSubmission {
    boolean needSaveToken() default false;
    boolean needRemoveToken() default false;
}


package com.mgear.samering.interceptor;

import java.lang.reflect.Method;
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;



/**
 * <p>
 * 防止重複提交過濾器
 * </p>
 *
 * 
 */
public class AvoidDuplicateSubmissionInterceptor extends HandlerInterceptorAdapter {
 
    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
            HandlerMethod handlerMethod ;
            if (handler instanceof HandlerMethod) {
            	handlerMethod = (HandlerMethod) handler;
            	} else {
            	return true;
            }
            Method method = handlerMethod.getMethod();
            AvoidDuplicateSubmission annotation = method.getAnnotation(AvoidDuplicateSubmission.class);
            if (annotation != null) {
                boolean needSaveSession = annotation.needSaveToken();
                if (needSaveSession) {
                    request.getSession(false).setAttribute("token",UUID.randomUUID().toString());
                }
 
                boolean needRemoveSession = annotation.needRemoveToken();
                if (needRemoveSession) {
                    if (isRepeatSubmit(request)) {
                        return false;
                    }
                    request.getSession(false).removeAttribute("token");
                }
            }
        return true;
    }
 
    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的配置文件里加入:

<!-- 設置重複提交校驗 -->
		<mvc:interceptor>
			<mvc:mapping path="/**"/>
			<mvc:exclude-mapping path="/common/**"/>
			<bean class="com.mgear.samering.interceptor.AvoidDuplicateSubmissionInterceptor"/>
		</mvc:interceptor>
		<mvc:interceptor>
			<mvc:mapping path="/**"/>
			<mvc:exclude-mapping path="/login/**"/>
			<mvc:exclude-mapping path="/common/**"/>
			<mvc:exclude-mapping path="/register/**"/>
			<bean class="com.mgear.samering.interceptor.CheckLoginInterceptor"/>
		</mvc:interceptor>
	</mvc:interceptors>

在相關方法中加入註解:

                @RequestMapping("/getRecommend_Info")
	        @AvoidDuplicateSubmission(needSaveToken = true)
		public String getRecommend_Info(String ApplyId,Model model,HttpSession session){
             @RequestMapping("/Recommend_save")
	     @AvoidDuplicateSubmission(needRemoveToken = true)
	    public @ResponseBody JSONObject Recommend_save(String json,HttpServletRequest request){

在頁面中加入

                <input type="hidden" name="token" value="${token}">,ajax提交的時候,將這個也提交


發佈了56 篇原創文章 · 獲贊 7 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章