国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - springmvc 防止表單重復提交的兩種方法

springmvc 防止表單重復提交的兩種方法

2021-11-03 12:08阿豪_mike Java教程

最近在本地開發測試的時候,遇到一個表單重復提交的現象。本文主要介紹了springmvc 防止表單重復提交的兩種方法,感興趣的可以了解一下

最近在本地開發測試的時候,遇到一個表單重復提交的現象。 因為網絡延遲的問題,我點擊了兩次提交按鈕,數據庫里生成了兩條記錄。其實這種現象以前也有遇到過,一般都是提交后把按鈕置灰,無法再次提交,這是很常見的客戶端處理的方式。 但是這不是從根本上解決問題,雖然客戶端解決了多次提交的問題,但是接口中依舊存在著問題。假設我們不是從客戶端提交,而是被其他的系統調用,當遇到網絡延遲,系統補償的時候,還會遇到這種問題

1、通過session中的token驗證

  • 初始化頁面時生成一個唯一token,將其放在頁面隱藏域和session中
  • 攔截器攔截請求,校驗來自頁面請求中的token與session中的token是否一致
  • 判斷,如果一致則提交成功并移除session中的token,不一致則說明重復提交并記錄日志

步驟1:創建自定義注解

?
1
2
3
4
5
6
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Token {
    boolean save() default false;
    boolean remove() default false;
}

步驟2:創建自定義攔截器(@slf4j是lombok的注解)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
@Slf4j
public class RepeatSubmitInterceptor extends HandlerInterceptorAdapter {
 
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        HandlerMethod handlerMethod = null;
        try {
            handlerMethod = (HandlerMethod)handler;
        } catch (Exception e) {
            return true;
        }
        Method method = handlerMethod.getMethod();
 
        Token token = method.getAnnotation(Token.class);
        if(token != null ){
            boolean saveSession = token.save();
            if(saveSession){
                request.getSession(true).setAttribute("token", UUID.randomUUID());
            }
 
            boolean removeSession = token.remove();
            if(removeSession){
                if(isRepeatSubmitSession(request)){
                    log.info("repeat submit session :" + request.getServletPath());
                    response.sendRedirect("/error/409");
                    return false;
                }
                request.getSession(true).removeAttribute("token");
            }
        }
        return true;
    }
 
    private boolean isRepeatSubmitSession(HttpServletRequest request){
        String sessionToken = String.valueOf(request.getSession(true).getAttribute("token") == null ? "" : request.getSession(true).getAttribute("token"));
        String clientToken =  String.valueOf(request.getParameter("token") == null ? "" : request.getParameter("token"));
        if(sessionToken == null || sessionToken.equals("")){
            return true;
        }
        if(clientToken == null || clientToken.equals("")){
            return true;
        }
        if(!sessionToken.equals(clientToken)){
            return true;
        }
        return false;
    }
 
}

步驟3:將自定義攔截器添加到配置文件

?
1
2
3
4
<mvc:interceptor>
 <mvc:mapping path="/**"/>
 <bean class="com.chinagdn.base.common.interceptor.RepeatSubmitInterceptor"/>
</mvc:interceptor>

使用案例

?
1
2
3
4
5
6
7
8
9
10
11
12
//save = true 用于生成token
@Token(save = true)
   @RequestMapping(value = "save", method = RequestMethod.GET)
   public String save(LoginUser loginUser, Model model) throws Exception {
       return "sys/user/edit";
   }
//remove = true 用于驗證token
@Token(remove = true)
   @RequestMapping(value = "save", method = RequestMethod.POST)
   public String save(@Valid LoginUser loginUser, Errors errors, RedirectAttributes redirectAttributes, Model model) throws Exception {
    //.....
   }

jsp頁面隱藏域添加token

?
1
<input type="hidden" name="token" value="${sessionScope.token}">

2、通過當前用戶上一次請求的url和參數驗證重復提交

攔截器攔截請求,將上一次請求的url和參數和這次的對比
判斷,是否一致說明重復提交并記錄日志

步驟1:創建自定義注解

?
1
2
3
4
5
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SameUrlData {
 
}

步驟2:創建自定義攔截器

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public class SameUrlDataInterceptor extends HandlerInterceptorAdapter {
 
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            //是否有 SameUrlData 注解
            SameUrlData annotation = method.getAnnotation(SameUrlData.class);
            if (annotation != null) {
                if (repeatDataValidator(request)) {//如果重復相同數據
                    response.sendRedirect("/error/409");
                    return false;
                } else {
                    return true;
                }
            }
            return true;
        } else {
            return super.preHandle(request, response, handler);
        }
    }
 
    /**
     * 驗證同一個url數據是否相同提交  ,相同返回true
     * @param httpServletRequest
     * @return
     */
    private boolean repeatDataValidator(HttpServletRequest httpServletRequest) {
        String params = JsonMapper.toJsonString(httpServletRequest.getParameterMap());
        String url = httpServletRequest.getRequestURI();
        Map<String, String> map = new HashMap<>();
        map.put(url, params);
        String nowUrlParams = map.toString();//
 
        Object preUrlParams = httpServletRequest.getSession().getAttribute("repeatData");
        if (preUrlParams == null) { //如果上一個數據為null,表示還沒有訪問頁面
            httpServletRequest.getSession().setAttribute("repeatData", nowUrlParams);
            return false;
        } else { //否則,已經訪問過頁面
            if (preUrlParams.toString().equals(nowUrlParams)) { //如果上次url+數據和本次url+數據相同,則表示城府添加數據
                return true;
            } else { //如果上次 url+數據 和本次url加數據不同,則不是重復提交
                httpServletRequest.getSession().setAttribute("repeatData", nowUrlParams);
                return false;
            }
        }
    }
}

步驟3:將自定義攔截器添加到配置文件

?
1
2
3
4
<mvc:interceptor>
 <mvc:mapping path="/**"/>
 <bean class="com.chinagdn.base.common.interceptor.SameUrlDataInterceptor"/>
</mvc:interceptor>

使用案例

?
1
2
3
4
5
6
//在controller層使用  @SameUrlData 注解即可
@SameUrlData
   @RequestMapping(value = "save", method = RequestMethod.POST)
   public String save(@Valid LoginUser loginUser, Errors errors, RedirectAttributes redirectAttributes, Model model) throws Exception {
    //.....
   }

到此這篇關于springmvc 防止表單重復提交的兩種方法的文章就介紹到這了,更多相關springmvc 防止表單重復提交內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://juejin.cn/post/6990963223486791688

延伸 · 閱讀

精彩推薦
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7482021-02-04
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 亚洲精品久久久久久下一站 | 亚洲啪啪 | 欧美黄色网 | 黄色一级大片免费 | 亚洲精品无 | 日韩在线电影 | 夜夜操操操操 | 国产在线观看91一区二区三区 | 黄色av免费在线播放 | 国产精品久久久久久久久久新婚 | 亚洲精品久久久久一区二区三区 | 日本 欧美 国产 | 亚洲精品一区二区三区不 | 久久综合影院 | 亚洲精品视频网 | 国产目拍亚洲精品99久久精品 | 日韩在线播放一区二区三区 | 99视频免费 | 色婷婷狠狠| 午夜影院免费看 | 国产精品亚洲精品 | 亚洲精品国产区欧美区在线 | 国产成在线观看免费视频 | 国产一区久久 | 亚洲人免费| 午夜亚洲 | 国产一级在线观看 | 亚洲一区在线观看视频 | 色婷婷精品国产一区二区三区 | 国产精品久久久久久久久久久久久 | 中文字幕亚洲欧美 | 国产成人99久久亚洲综合精品 | 超碰97中文 | 福利社午夜影院 | 一级电影网 | 精品国产欧美一区二区 | 亚洲字幕网 | 中国精品一区二区 | 日本在线中文 | 亚洲视频在线不卡 | 国产99久久 |