SpringMVC表單防止重複提交

利用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,不一致則重複提交。(過濾器會校驗)
發佈了74 篇原創文章 · 獲贊 88 · 訪問量 35萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章