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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Struts2框架学习之七:避免表单重复提交

發布時間:2025/3/19 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Struts2框架学习之七:避免表单重复提交 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

防止表單重復提交在web開發中是一個經常遇到的問題,一般來避免重復提交有兩種方式:客戶端JavaScript代碼實現和服務端代碼實現。這里主要介紹服務端的實現方式。在服務端實現表單重復提交的基本原理是:通過創建一個Session對象,并產生一個令牌值,將這個令牌值作為隱藏域隨表單一起發送給客戶端,同時在Session中保存令牌值。在用戶提交表單的時候判斷提交參數的令牌值與Session中的是否相等,如果相等則清除,不再使用這個令牌值,,然后執行后續的處理;如果兩者不相等,表示已經提交過表單,服務端產生一個新的令牌值并保存到Session中。當用戶下次訪問的的時候,將新產生的領牌值發送到客戶端。

Struts2的實現方式

在Struts2中通過使用攔截器來實現的,機制與前言中采用令牌的方式是一樣的??梢酝ㄟ^兩種方式實現避免重復表單(實際上就是兩個不同的攔截器):token攔截器和tokenSession攔截器。由于在struts-default.xml的默認攔截器棧中并沒有將這兩個攔截器作為默認實現,所以需要在action中手動添加這兩個攔截器。這兩種方式的區別在于:使用token攔截器重復提交表單的時候,瀏覽器會跳轉到一個錯誤頁面,而使用更tokenSession攔截器重復提交表單的話是不會跳轉的,仍然在成功之后頁面。需要注意的是,使用者兩個攔截器重復提交表單的時候,都只會向服務器提交一次請求,所以這種方式可以有效降低服務器的負擔。

具體的例子

在使用以上攔截器進行測試的時候,需要如下步驟:
步驟一:編寫login.jsp、success.jsp和error.jsp三個頁面
login.jsp

... <s:form action="tokenWait" namespace="/" method="post"><s:textfield label="用戶名" name="user.username"></s:textfield><s:password label="密碼" name="user.password"></s:password><!-- 這個標簽不能少 --><%-- <s:token></s:token> --%><s:submit value="登錄"></s:submit></s:form>...

success.jsp

... <s:property value="user.username"/>,<%=new Date() %> ...

error.jsp

<html> <body><!-- 登錄失敗,請重新登錄<a href="login.jsp">返回</a> -->您已經提交過表單了! </body> </html>

步驟二:編寫action

package action;import java.util.ArrayList; import java.util.List;import bean.User;import com.opensymphony.xwork2.ActionSupport;public class TokenAction extends ActionSupport {private static final long serialVersionUID = 1L;private User user;@Overridepublic String execute() throws Exception {Thread.sleep(3000);List<User> users = new ArrayList<User>();users.add(user);for (User user : users) {System.out.println(user);}return SUCCESS;}public User getUser() {return user;}public void setUser(User user) {this.user = user;}}

步驟三:配置struts.xml

<!-- 避免表單重復提交 --><action name="token" class="action.TokenAction"><!-- 配置Token攔截器 --><interceptor-ref name="defaultStack"></interceptor-ref><interceptor-ref name="token"></interceptor-ref><!-- 如果重復提交,則跳轉到error.jsp --><result name="invalid.token">/error.jsp</result><result>/success.jsp</result></action><action name="tokenSession" class="action.TokenAction"><!-- 配置TokenSession攔截器 --><interceptor-ref name="defaultStack"></interceptor-ref><interceptor-ref name="tokenSession"></interceptor-ref><!-- 如果重復提交,則跳轉到error.jsp --><result name="invalid.token">/error.jsp</result><result>/success.jsp</result></action>

這里需要提出的是,action中name屬性為invalid.token的result是不可少的。

步驟四:發布測試
經過測試,發現使用token攔截器在重復提交表單的時候會轉到error.jsp,而使用tokenSession攔截器在重復提交表單的時候不會轉到error.jsp。

顯示等待頁面

有時候在action需要處理較長時間的時候,一般是5到10分鐘,在這種情況下向用戶顯示一個等待頁面可能會比較友好一些。在Struts2中通過使用execAndWait攔截器就可以非常輕松實現這點。

execAndWait的工作機制:

execAndWait攔截器能夠讓一個A執行時間超過5分鐘的Action在后臺運行,并向用戶顯示一個等待頁面。之所以是5分鐘是因為這樣防止HTTP請求超時。當一個請求到來的時候,execAndWait攔截器會創建一個線程來執行Session,然后返回一個等待頁面,這樣用戶就知道請求在處理中。等待頁面包含了自動刷新功能,在超時之前,瀏覽器會向初始請求的action再次發起請求,以便知道后臺action是否已經執行完畢。如果action仍然沒有執行完畢,則繼續顯示等待頁面,如果action已經執行完畢,則等待頁面將發生跳轉,向用戶處理結束之后的頁面。

execAndWait攔截器有以下幾個參數:

  • threadPriority:執行線程的優先級
  • delay:指定在顯示等待頁面前初始的延遲加載時間,單位是毫秒
  • delaySleepInternal:指定檢查后臺線程是否執行完畢的時間間隔,必須和delay參數一起使用,單位是毫秒,默認是100毫秒。表示每100毫秒進行一次檢查

使用execAndWait攔截器顯示等待頁面,首先需要編寫一個等待頁面:

... <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>等待頁面</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="refresh" content="3;url=tokenWait.action"> </head><body>您的請求正在處理,請稍等。<span id="time" style="font-size:30px;color:red;font-face:隸書"></span>秒后頁面將自動跳轉<script type="text/javascript">var start = 3;var step = -1;function timer () {document.getElementById("time").innerHTML = start;if(start > 0){start = start + step;}setTimeout("timer()",1000);}window.onload = timer;</script> </body> </html>

在head 標簽中需要添加自動刷新meta標簽,不然是不會出發自動檢查的。在這個等待頁面中,表示3秒后就會跳轉到成功頁面。

之后是添加execAndWait攔截器的配置:

<!-- 顯示自動等待頁面 --><action name="tokenWait" class="action.TokenAction"><result name="wait">/wait.jsp</result><result>/success.jsp</result><interceptor-ref name="defaultStack"><!-- 把default方法排序在外,表示不攔截!default.action --><param name="excludeMethods">default</param></interceptor-ref><interceptor-ref name="execAndWait"><!-- 把default方法排序在外,表示不攔截!default.action --><param name="excludeMethods">default</param><!-- 等待延遲時間 --><param name="delay">1000</param></interceptor-ref></action>

注意到TokenAction類中,使用Tread.sleep(3000),表示通過讓線程休眠的方式延長action的處理時間,還有一點要注意的是struts.xml中execAndWait攔截器的delay參數的值需要小于Thread.sleep(time)的時間。這樣就能保證在action處理結束之前完成顯示等待頁面,不然很可能會直接success.jsp頁面了。

總結

以上是生活随笔為你收集整理的Struts2框架学习之七:避免表单重复提交的全部內容,希望文章能夠幫你解決所遇到的問題。

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