1. 程式人生 > >JFinal的攔截器防止表單重複提交

JFinal的攔截器防止表單重複提交

       前段時間師傅讓我整理一份防止表單重複提交的方案,平常所用的提交按鈕後通過js禁止提交等方式也可以的,若是禁用js可能就尷尬了,不過也沒幾個人會這麼幹。起初也是在網上百度各種資料照貓畫虎搞一套的,畢竟目前水平低低的我確實需要多學習,先不說創造,乖乖吸取前輩們的經驗為上策。

        原理:url請求指定頁面時,用攔截器攔截,生成一個唯一的識別符號(token),在新建頁面中Session儲存token隨機碼,當儲存(提交)時驗證,通過後刪除,當再次點選儲存時由於伺服器端的Session中已經不存在了,所有無法驗證通過。

注:提交儲存方法與頁面內表單校驗(比如姓名是否重複的校驗)方法不能共用一個方法。

 一:

      註解類:

        /**
         * 防止重複提交 - 引數為方法名
         */
        @Target( ElementType.METHOD)
        @Retention(RUNTIME)
        @Documented
        public @interface RepeatSaveParam {
                String value() default "";
         }

二:

     第一個攔截器:目的是在進入指定頁面時攔截生成token並存放session中

  public class ValidateTokenInterceptor implements Interceptor {

              @Override
              public void intercept(ActionInvocation inv) {
                          RepeatSaveParam repeatSaveParam = inv.getMethod().getAnnotation(RepeatSaveParam.class);
                          if (repeatSaveParam != null && StrKit.notBlank(repeatSaveParam.value())){
                                    createToken(inv.getController(),"validatorToken"+repeatSaveParam.value(), 30*60);

                                    //  設定頁面隱藏框的name 屬性  validatorToken+提交時的方法名
                                    inv.getController().setAttr("validatorTokenName","validatorToken"+repeatSaveParam.value());
                           }
                           inv.invoke();
               }

   }

三:

   第二個攔截器: 提交時校驗頁面中的token與session中的token校驗,一致通過並刪除,此後無效。

public class RepeatSaveInterceptor implements Interceptor{

               @Override
               public void intercept(ActionInvocation inv) {
                boolean token = com.jfinal.token.TokenManager.validateToken(inv.getController(), "validatorToken"+inv.getMethodName());
                        if(token){
                                 inv.invoke(); //繼續執行action中的方法
                         }
              }

    }

四:

     action或controller中:
          

           @Before(ValidateTokenInterceptor.class)
           @RepeatSaveParam("overtimeApplySave")  // overtimeApplySave為提交時url的方法名稱
           public void applyAdd() {
                   // 進入指定頁面
                   render(SysParamUtil.getLangRender("apply_add.jsp"));
           }

            @Before(RepeatSaveInterceptor.class)
            public void overtimeApplySave() throws BizException {

                       //處理業務

                   renderJson("result", "ok");

            }

五:       apply_add.jsp頁面中只需要 ${token} 就可以了  它是隱藏的文字框 可以研究下攔截器那幾個方法,不算太難

             name屬性:validatorToken+提交時的方法名

             value值:生成的token

  接下來就可以測試了!!!!!!!!!!!!

  點選再多次我們只做處理,也可以提醒使用者,但感覺沒必要,還是結合自己實際需求去做。若是需要提示再第二個攔截器else裡面處理json格式返回,ajax接受提示即可。