1. 程式人生 > >spring mvc 防止重複提交表單的兩種方法,推薦第二種

spring mvc 防止重複提交表單的兩種方法,推薦第二種

第一種方法:判斷session中儲存的token

比較麻煩,每次在提交表單時都必須傳入上次的token。而且當一個頁面使用ajax時,多個表單提交就會有問題。

註解Token程式碼:

  1. package com.thinkgem.jeesite.common.repeat_form_validator;  
  2. import java.lang.annotation.ElementType;  
  3. import java.lang.annotation.Retention;  
  4. import java.lang.annotation.RetentionPolicy;  
  5. import java.lang.annotation.Target;  
  6. /** 
  7.  * 頁面form   token 
  8.  * @author Administrator 
  9.  * 
  10.  */
  11. @Target(ElementType.METHOD)  
  12. @Retention(RetentionPolicy.RUNTIME)  
  13. public@interface FormToken {  
  14.     boolean save() defaultfalse;  
  15.     boolean remove() defaultfalse;  
  16. }  
攔截器TokenInterceptor程式碼:
  1. package com.thinkgem.jeesite.common.repeat_form_validator;  
  2. import java.lang.reflect.Method;  
  3. import java.util.UUID;  
  4. import javax.servlet.http.HttpServletRequest;  
  5. import javax.servlet.http.HttpServletResponse;  
  6. import org.springframework.web.method.HandlerMethod;  
  7. import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;  
  8. publicclass
     FormTokenInterceptor extends HandlerInterceptorAdapter {  
  9.     @Override
  10.     publicboolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  
  11.         if (handler instanceof HandlerMethod) {  
  12.             HandlerMethod handlerMethod = (HandlerMethod) handler;  
  13.             Method method = handlerMethod.getMethod();  
  14.             FormToken annotation = method.getAnnotation(FormToken.class);  
  15.             if (annotation != null) {  
  16.                 boolean needSaveSession = annotation.save();  
  17.                 if (needSaveSession) {  
  18.                     request.getSession(false).setAttribute("formToken", UUID.randomUUID().toString());  
  19.                 }  
  20.                 boolean needRemoveSession = annotation.remove();  
  21.                 if (needRemoveSession) {  
  22.                     if (isRepeatSubmit(request)) {  
  23.                         returnfalse;  
  24.                     }  
  25.                     request.getSession(false).removeAttribute("formToken");  
  26.                 }  
  27.             }  
  28.             returntrue;  
  29.         } else {  
  30.             returnsuper.preHandle(request, response, handler);  
  31.         }  
  32.     }  
  33.     privateboolean isRepeatSubmit(HttpServletRequest request) {  
  34.         String serverToken = (String) request.getSession(false).getAttribute("formToken");  
  35.         if (serverToken == null) {  
  36.             returntrue;  
  37.         }  
  38.         String clinetToken = request.getParameter("formToken");  
  39.         if (clinetToken == null) {  
  40.             returntrue;  
  41.         }  
  42.         if (!serverToken.equals(clinetToken)) {  
  43.             returntrue;  
  44.         }  
  45.         returnfalse;  
  46.     }  
  47. }  
然後在spring MVC的配置檔案里加入:
  1. <mvc:interceptors>  
  2.     <mvc:interceptor>  
  3.             <mvc:mapping path="/**"/>  
  4.             <bean class="com.thinkgem.jeesite.common.repeat_form_validator.FormTokenInterceptor"/>  
  5.         </mvc:interceptor>  
  6.     </mvc:interceptors>  
關程式碼已經註釋,相信你能看懂。
關於這個方法的用法是:
在需要生成token的controller上增加@FormToken(save=true),而在需要檢查重複提交的controller上新增@FormToken(remove=true)就可以了。
另外,你需要在view裡在form裡增加下面程式碼:
  1. <inputtypeinputtype="hidden"name="formToken"value="${formToken}"/>

已經完成了,去試試看你的資料還能重複提交了吧。

注意在ajax提交時 要加上 formToken引數

第二種方法(判斷請求url和資料是否和上一次相同)

推薦,非常簡單,頁面不需要任何傳入,只需要在驗證的controller方法上寫上自定義註解即可

寫好自定義註解

  1. package com.thinkgem.jeesite.common.repeat_form_validator;  
  2. import java.lang.annotation.ElementType;  
  3. import java.lang.annotation.Retention;  
  4. import java.lang.annotation.RetentionPolicy;  
  5. import java.lang.annotation.Target;  
  6. /** 
  7.  * 一個使用者 相同url 同時提交 相同資料 驗證 
  8.  * @author Administrator 
  9.  * 
  10.  */
  11. @Target(ElementType.METHOD)  
  12. @Retention(RetentionPolicy.RUNTIME)  
  13. public@interface SameUrlData {  
  14. }  
寫好攔截器
  1. package com.thinkgem.jeesite.common.repeat_form_validator;  
  2. import java.lang.reflect.Method;  
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5. import javax.servlet.http.HttpServletRequest;  
  6. import javax.servlet.http.HttpServletResponse;  
  7. import org.springframework.web.method.HandlerMethod;  
  8. import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;  
  9. import com.thinkgem.jeesite.common.mapper.JsonMapper;  
  10. /** 
  11.  * 一個使用者 相同url 同時提交 相同資料 驗證 
  12.  * 主要通過 session中儲存到的url 和 請求引數。如果和上次相同,則是重複提交表單 
  13.  * @author Administrator 
  14.  * 
  15.  */
  16. publicclass SameUrlDataInterceptor  extends HandlerInterceptorAdapter{  
  17.       @Override
  18.         publicboolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  
  19.             if (handler instanceof HandlerMethod) {  
  20.                 HandlerMethod handlerMethod = (HandlerMethod) handler;  
  21.                 Method method = handlerMethod.getMethod();  
  22.                 SameUrlData annotation = method.getAnnotation(SameUrlData.class);  
  23.                 if (annotation != null) {  
  24.                     if(repeatDataValidator(request))//如果重複相同資料
  25.                         returnfalse;  
  26.                     else
  27.                         returntrue;  
  28.                 }  
  29.                 returntrue;  
  30.             } else {  
  31.                 returnsuper.preHandle(request, response, handler);  
  32.             }  
  33.         }  
  34.     /** 
  35.      * 驗證同一個url資料是否相同提交  ,相同返回true 
  36.      * @param httpServletRequest 
  37.      * @return 
  38.      */
  39.     publicboolean repeatDataValidator(HttpServletRequest httpServletRequest)  
  40.     {  
  41.         String params=JsonMapper.toJsonString(httpServletRequest.getParameterMap());  
  42.         String url=httpServletRequest.getRequestURI();  
  43.         Map<String,String> map=new HashMap<String,String>();  
  44.         map.put(url, params);  
  45.         String nowUrlParams=map.toString();//
  46.         Object preUrlParams=httpServletRequest.getSession().getAttribute("repeatData");  
  47.         if(preUrlParams==

    相關推薦

    spring mvc 防止重複提交方法推薦第二

    第一種方法:判斷session中儲存的token 比較麻煩,每次在提交表單時都必須傳入上次的token。而且當一個頁面使用ajax時,多個表單提交就會有問題。 註解Token程式碼: package com.thinkgem.jeesite.common.re

    防止重複提交-思路

    防止重複提交表單 $c =md5(serialize($this->request->request())); $find = session($c); if($find){ if($find['expire']+2-time()>=0){ re

    記一次 thinkphp5令牌驗證防止重複提交

    因為專案需要表單提交,可是發現了必須要防止使用者提交,經過了幾個小時的百度旅遊總算找到的方法,其實說到底還是看官方手冊來的頭緒,以後看來要多看。。。。。。。 其實好像就是驗證器中加入token的驗證而已,擼程式碼吧 首先在html的from中加入下列程式碼,其實官方手冊有說明的 {:token()

    springmvc 攔截器 防止重複提交

    第一種方法:判斷session中儲存的token 比較麻煩,每次在提交表單時都必須傳入上次的token。而且當一個頁面使用ajax時,多個表單提交就會有問題。 註解Token程式碼: package com.thinkge

    分享防止重複提交【php】

    表單重複提交是在多使用者Web應用中最常見、帶來很多麻煩的一個問題。有很多的應用場景都會遇到重複提交問題,比如: 點選提交按鈕兩次。點選重新整理按鈕。使用瀏覽器後退按鈕重複之前的操作,導致重複提交表單。使用瀏覽器歷史記錄重複提交表單。瀏覽器重複的HTTP請求。   幾種防止

    Spring MVC 測試 | 模擬提交

    在 Spring 4 MVC 單元測試例子 一文中利用Spring test 框架進行了簡單的測試,程式碼mockMvc.perform(get("/SayHello/getAnswer"))使用get()方法傳送了一個GET請求。 現在需求變了,需要提交一個

    前端頁面js防止重複提交

    1.第一個方法是我自己想的,就是設定submit按鈕屬性為disabled,然後當後臺請求成功移除這個屬性。 2.第二個是一個面試官告訴我的,我個人覺得和我第一個異曲同工,就是在點選的時候加一個class屬性,然後js判定是否有這個class,如果有的話不再重複提交, 後臺

    THINKPHP 防止重複提交 自己實現token

    首先在專案function.php 定義幾個方法。 //建立TOKEN function creatToken() { $code = chr(mt_rand(0xB0, 0xF7)) . chr(mt_rand(0xA1, 0xFE)) . chr(mt_ran

    Spring MVC 回退重新整理重複提交

        基於Spring MVC進行Java Web開發時,如果使用表單進行提交資料,然後跳轉到某個URL由Controller進行處理,最後返回邏輯檢視,框架會通過viewResolver來解析具體的View,然後向返回給瀏覽器顯示【參考】。 <bean

    Spring MVC框架在進行提交自動封裝成物件提交在以物件的形式入參

    最近做了一個超市訂單管理系統的專案,使用的是Spring MVC 和Spring 框架。 如上圖:進行新使用者新增。此處jsp頁面程式碼如下: <div class="right"> <div class="location"

    spring mvc 配合ajax進行提交(有檔案上傳)並且提醒使用者提交成功

    1. 首先匯入jquery-form.js 外掛   ---->   用來提交表單 匯入layer.css 以及 layer.js ----->   用來提醒使用者(這是一個比較成熟的彈出層框架) 2.原始碼 html部分: <form enctyp

    客戶端服務端防止使用者重複提交

    一、什麼是表單重複提交? 當網路有延遲時,使用者提交的表單等資料還沒有完成此次提交,但使用者又多次點選提交,造成使用者資料在資料庫或儲存中被提交多次。 利用執行緒延遲,簡單模擬重複提交。 表單頁面為form.html [html] view plain

    Struts2中重複提交分析

    原因:Struts2提交表單完成新增資料等操作後,再去重新整理頁面會彈出警告,提示資訊會再次被提交(同樣的表單資料) 解決:在action中配置攔截器 1.需要在提交資料的表單<form> 內增加<s:token></s:token> 在js

    spring-mvc @ModelAttribute 繫結資料到VO

    場景:任何提交表單的時候 目的:不去手工獲取值,藉助spring-mvc 的內建機制,把表單轉換為VO 代價:在方法引數中使用@ModelAttribute註解 注意:表單中的name值要與VO物件中的屬性值對應,而且表單中不需要攜帶VO物件名 栗子: @RequestMa

    避免重新整理頁面時重複提交資料

    <?php // session_start() 會建立新會話或者重用現有會話。 如果通過 GET 或者 POST 方式,或者使用 cookie 提交了會話 ID, 則會重用現有會話。 session_start(); if( ! empty($_POST['sub']) ) {

    解決 php提交到當前頁面重新整理會重複提交 的問題

    下午有一個朋友問我這個問題,其實解決辦法很簡單: 只需要在表單裡生成一個token(隨機字串),然後用個input裝起來,設定hidden。第一次post處理完資料後把token存入session,接下來每次post判斷一下token跟session中的一不一樣,一樣則說明

    spring mvc ajax請求form轉換成json

    在使用jquery傳送ajax請求的時候,通過jquery的serialize()方法對錶單進行處理髮送到服務端是比較方便的。有一種場景是,欄位大部分在form表單下,個別欄位需要組裝,如果需要組裝的欄位比較簡單,可以使用serializeArray()將form序列化成ar

    Django通過Ajax利用FormData動態提交(包括檔案字串)

    0 需求背景 有的時候我們上傳表單,經過後臺處理之後再分發回原來頁面,這時必定會重新整理這個頁面。為了解決這個問題,我們採用JS動態提交表單元素,如:file、text等型別,可以很好的解決這一問題。 1 DOM結構 <form method="post" enctype=

    基於jquery的實現非同步跨域提交的實現程式碼需要的朋友可以參考下。

    1.使用post提交方式 2.構造表單的數格式 3.結合form表單的submit呼叫ajax的回撥函式。 使用 jQuery 非同步提交表單程式碼: <html xmlns="http://www.w3.org/1999/xhtml"> <he

    jQuery Mobile中無法提交的解決方法

    jquery mobile預設是使用ajax提交表單的,如果要像平常PHP一樣的流程接收引數,可以把AJAX禁用: 只在加上data-ajax="false"就可以了。 <form method="post" action="jqdemo.php" data-aja