日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java防止表单二次提交_防止表单重复提交

發布時間:2025/3/21 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java防止表单二次提交_防止表单重复提交 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在Web開發中表單的重復提交是很嚴重的問題,重復提交成功會產生垃圾數據消耗不必要的資源,更嚴重的是如果遇到惡意刷庫的情況垃圾數據更是數不勝數。在正常使用過程中產生重復提交的情況也有多重情況:鼠標連擊、回退提交、刷新提交、網絡延遲用戶重復提交等。

防止重復提交的方法分兩大類就是客戶端、服務端(這是廢話了)。客戶端主要是用js對按鈕的限制,一次點擊后屏蔽按鈕或者是直接跳轉等待頁面,服務端思路為客戶端加token進行驗證。客戶端就不做詳細介紹,主要介紹服務端的控制。

1、客戶端存儲

就是在客戶端不同的地方存儲兩個token,在服務端進行校驗。在Form表單中存儲一個token利用隱藏域,在Cookie中存儲一個(也可以都放到form表單中兩個不同的隱藏域)。檔form表單提交的時候,對這兩個token進行驗證,相同則允許提交否則阻止提交。

優點:

不占用服務器資源

實施起來簡單,易上手

缺點:

容易偽造(防君子不防小人)

占用網絡資源(或許不是那么明顯)

詳細介紹一下客戶端分布存儲在Form表單中和Cookie中的情況。

客戶端的實現如下:

packagecn.simple.token;importjavax.servlet.http.Cookie;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importorg.apache.commons.lang.StringUtils;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;/*** 雙客戶端驗證

*@authorldm

* @Date 2016年6月16日*/@Service("clientTokenProcesser")public class ClientTokenProcesser extendsTokenProcesser {

@Autowired

HttpServletResponse response;

@Overridepublic booleanvalidToken(HttpServletRequest request) {

String formToken=request.getParameter(getTokenField()).toString();

System.out.println("formToken:"+formToken);if(StringUtils.isEmpty(formToken))

{

printException("表單中沒有token");return false;

}

Cookie[] cookies=request.getCookies();if(cookies==null)

{

printException("cookie 中沒有token");

}for(Cookie cookie : cookies) {if(cookie.getName().equals(getTokenKey(request)))

{

String cookieValue=cookie.getValue();

System.out.println("cookieToken:"+cookieValue);if(cookieValue.equals(formToken))

{return true;

}

}

}return false;

}private voidprintException(String msg) {

Exception e= newRuntimeException(msg);

e.printStackTrace();

}

@OverridepublicString getTokenKey(HttpServletRequest request) {

String cookieKey= getTokenField() + "_cookie";returncookieKey;

}

@Overridepublic voidsaveToken(HttpServletRequest request) {

String token=MakeToken.getInstance().getToken();

request.setAttribute(getTokenField(), token);if (response == null) {throw new RuntimeException("HttpServletResponse is null");

}

Cookie cookie= newCookie(getTokenKey(request), token);

response.addCookie(cookie);

}

@OverridepublicString getClientToken(HttpServletRequest request) {

Object token=request.getParameter(getTokenField());if (token == null) {return null;

}else{returntoken.toString();

}

}

}

View Code

2、雙向存儲

客戶端和服務端的token各自獨立存儲,客戶端存儲在Cookie或者Form的隱藏域(放在Form隱藏域中的時候,需要每個表單)中,服務端存儲在Session(單機系統中可以使用)或者其他緩存系統(分布式系統可以使用)中。

優點:

安全性高(幾乎是無法偽造的)

網絡資源相對于前者有所減少

缺點:

整個系統實施起來較第一種方法的時候復雜度增加

詳細介紹一下服務端存儲在session中客戶端存儲在Cookie中

SessionTokenProcesser實現如下:

packagecn.simple.token;importjavax.servlet.http.Cookie;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjavax.servlet.http.HttpSession;importorg.apache.commons.lang.StringUtils;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;/*** 服務端用Session存儲

*

*@authorldm

* @Date 2016年6月16日*/@Service("sessionTokenProcesser")public class SessionTokenProcesser extendsTokenProcesser {

@Autowired

HttpServletResponse response;

@Overridepublic booleanvalidToken(HttpServletRequest request) {

String clientToken=getClientToken(request);if(StringUtils.isEmpty(clientToken)) {return false;

}

HttpSession session= request.getSession(false);if (session == null) {return false;

}

String tokenKey=getTokenKey(request);

Object tokenObj=session.getAttribute(tokenKey);if(tokenObj==null)

{

rethrow("服務端不存在當前token,請重新請求表單");

}

String serverToken=tokenObj.toString();

session.removeAttribute(tokenKey);

System.out.println("remove server token:" +serverToken);returnclientToken.equals(serverToken);

}

@OverridepublicString getTokenKey(HttpServletRequest request) {returngetTokenField();

}

@Overridepublic voidsaveToken(HttpServletRequest request) {

HttpSession session=request.getSession();

String tokenKey=getTokenKey(request);

Object tokenObj=session.getAttribute(tokenKey);

String token;if (tokenObj == null) {

token=MakeToken.getInstance().getToken();//服務端保存token

session.setAttribute(tokenKey, token);

}else{

token=tokenObj.toString();

}

System.out.println("current token:" +token);//寫入cookie

Cookie cookie = newCookie(getTokenField(), token);

response.addCookie(cookie);

}private voidrethrow(String message) {

RuntimeException e= newRuntimeException(message);throwe;

}

@OverridepublicString getClientToken(HttpServletRequest request) {

Cookie[] cookies=request.getCookies();if (cookies == null) {

rethrow("沒有讀取到客戶端的cookie");return null;

}for(Cookie cookie : cookies) {if(cookie.getName().equals(getTokenKey(request))) {

String cookieValue=cookie.getValue();returncookieValue;

}

}

rethrow("客戶端cookie中沒有存儲token");return null;

}

}

View Code

總結

以上是生活随笔為你收集整理的java防止表单二次提交_防止表单重复提交的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。