禍兮福所倚,福兮禍所伏

          想隨便當個小職員,隨便賺點錢然后隨便和一個不美也不丑的普通女孩結婚,隨便生兩個孩子,先生個女孩再生個男孩。等女兒結婚,兒子也能夠獨擋一面的時候,然后就退休,然后每天過著下著象棋和圍棋的悠閑生活。然后在自己的老婆死之前自己先老死這種生活多美好呀!

          BlogJava 首頁 新隨筆 聯系 聚合 管理
            0 Posts :: 8 Stories :: 0 Comments :: 0 Trackbacks

              開發基于瀏覽器的客戶端總是會遇到表單重復提交的問題。很明顯的在一個商業應用中重復提交是不希望發生的。struts提供一個機制,使用Action基類的generateToken方法產生一個token來保護模型層避免受到表單多次提交的影響。為了控制事務的完整性和原子性,在使用ActionForward選擇下一個視圖前要調用request handler的saveToken方法。saveToken方法調用generateToken方法創建一個唯一標識符,然后用Action.TRANSACTION_TOKEN_KEY保存到session中。表單標簽從session中獲得token然后用Constants.TOKEN_KEY保存到隱藏字段中。在接下來的請求中,request handler通過調用action基類的isTokenValid方法檢查token的合法性。如果該方法返回false,request handler必須實現合適的邏輯處理遇到的問題。一個處理的例子如下所示:
              if (!isTokenValid(request)) {
                errors.add(ActionErrors.GLOBAL_ERROR,
                new ActionError("transaction.token.invalid"));
                //errors object is of type ActionErrors
              }
              isTokenValid同步處理session對象的token來阻止表單重復提交請求。在request handlers中,isTokenValid方法必須跟一個resetToken來從session中移除token;這樣可以保證任何后續請求都將導致isTokenValid返回fa,因此組織表單多次提交。request handler的saveToken方法應該被調用來重建一個新的事務token滿足下次的請求。
              獲得表單數據
              jsp規范使用在請求時的JavaBeans中提取和存儲表單數據。然而,這種方式使表現層和JavaBeans強耦合;而且HTML文檔的創建者還必須知道這些組件以及他們在頁面中的正確用法。因為JavaBeans能夠通過標簽或另一個服務器組件在一個特定的范圍創建和使用,這樣可能會造成在不同組件共享的JavaBean的生命周期管理產生問題。struts提供了一個機制提取,存儲,校驗表單數據。同時也客服了的缺點。例子略。
              例子映射一個JavaBean類型為packageName.customerProfileForm用name=customerProfileForm (唯一標識),name=customerProfileForm; request handler通過輸入請求中的路徑/editCustomerProfile唯一標識。 表單的創建和使用在下面的圖片中解釋。

              首先,我們將用一個簡單的JavaBeans對象研究表單的處理機制。這些對象是作為ActionForm對象實現的。我們接下來要討論使用DynaActionForm進行表單處理,這個DynaActionForm對象能夠支持才請求時動態設置屬性。


              用FormTag初始化ActionForm對象
              用前面介紹的方式FormTag初始化ActionForm對象,在HTML表單中的action URL對應配置節點,該節點通過配置對于formbean。FormTag的action屬性定義的URL通過配置描述文件中的的路徑結構轉換成URL。通過擴展名映射,實現了用    FormTag調用RequestUtils.createActionForm方法,該方法通過名字匹配元素的名字來搜索ActionFormBean配置對象((ActionFormBean是運行時表現形式)。使用元素創建一個新的ActionForm實例,如實例存在,則FormTag會在存在的form bean調用ActionForm.reset方法清除數據,為下一次請求的表單數據做準備。范圍定義在元素的scope屬性中;新的ActionForm實例或者重新初始化的實例保存在該屬性定義的范圍中。


              用ActionForm存儲表單數據   
              被繼承的ActionForm對象是用來存放表單請求對象參數的,因此他們是和用戶緊耦合的。一個ActionForm子類是一個帶屬性存取方法的JavaBean,這些屬性與HttpServletRequest對象的參數對應。如果一個ActionForm對象通過FormTag創建(前面介紹了),那么在接下來通過FormTag解析的表單請求將由RequestProcessor在特定范圍處理。表單通過相關的action映射標識找到。RequestProcessor為重置表單屬性,通常表單帶有請求時間參數,然后調用表單對象的validate方法完成服務端校驗用戶輸入。僅當ActionMapping對象的校驗屬性設為true時,validate方法才會被調用。這是一個默認的行為。使用request.getParameterValues(parameterName)獲得一個String數組對象,這個對象用來存放表單數據;在請求參數類型轉換一節將做解釋。校驗結構是一個ActionErrors對象(在錯誤處理一節解釋了),它使用org.apache.struts.taglib.html.ErrorsTag顯示校驗錯誤給用戶。ActionForm也能存儲中間層模型狀態,這些狀態數據接下來會視圖(jsp)引用并展示給用戶。
              一個ActionForm類也可以被RequestProcessor創建。這種情況發生在導航到URL,該URL映射到控制器servlet而不是jsp,相關的action映射定義了表單屬性。在這種情況下,RequestProcessor搜索form bean的嘗試會導致創建一個新的ActionForm對象,如果在特定范圍沒有找到的話,或者在特定范圍通過元素的名字屬性找到ActionForm對象;當一個表單對象被RequestProcessor找到,將傳遞給請求處理對象的execute方法。一個ActionForm對象也能被請求處理器創建。
              表單對象的創建的目的是為了提供中間層模型狀態給jsp時應該使用請求范圍;這樣可以保證在他們的有效性過期后對象不會再被使用。默認的所有表單保存在session范圍。在session中存在的表單對象超過了他們的有效性范圍會導致浪費內存,因此,請求處理者必須跟蹤存儲在session中的表單對象的生命周期。獲得表單數據的一個好的實踐是用單一的form bean關聯跨越服務端用戶交互的表單。form beans也能夠存儲中間層模型狀態,這個狀態在相應用戶時,通過定制的標簽適配到用戶視圖中。標簽用來避免在視圖層混合java代碼,因此導致了一個好的分工,web開發團隊處理標記,應用開發團隊處理java代碼。標簽區分了中間層處理邏輯;這些邏輯可能相當復雜,比如處理嵌套對象或通過集合迭代對象。

              用動態屬性創建ActionForm對象
              DynaActionForm對象是帶動態集合屬性的對象。DynaActionForm擴展了ActionForm對象;通過在struts-config.xml文件中聲明來創建form對象。例子略。RequestProcessor創建,操作,校驗DynaActionForm的方式和操作ActionForm是一致的,也就是說對于在DynaActionForm的動態屬性(定義在元素的動態集合屬性),請求對象參數是可操作的。其它參數被簡單跳過。

              請求參數類型轉換
              這節討論request.getParameterValues(parameterName)獲得的String數組類型怎樣轉換到表單對象的對應屬性類型上。下面是支持的目標類型列表。
          java.lang.BigDecimal
          java.lang.BigInteger
          boolean and java.lang.Boolean
          byte and java.lang.Byte
          char and java.lang.Character
          double and java.lang.Double
          float and java.lang.Float
          int and java.lang.Integer
          long and java.lang.Long
          short and java.lang.Short
          java.lang.String
          java.sql.Date
          java.sql.Time
          java.sql.Timestamp
              目標類型,也就是說和表單對象屬性關聯的類型,是通過自省機制找到的;一個特定struts定制的自省機制是在DynaActionForm對象中使用的。struts也支持索引屬性,parameterName[n];索引從0開始。這種命名轉換的form bean的方法是通過按照下面定義的javabeans規范描述的,使用了索引屬性模式。下面的方法用來處理所有的索引屬性的數組元素。
          public [] get();
          public void set([] value);
          下面的方法是用來處理單獨的數組元素
          public get(int index)
          public void set(int index, value)
          下面描述了使用簡單的屬性和索引屬性的語法。
              1.當bean的屬性是數組,且請求參數名沒有使用索引符號parameterName[n]時,由request.getParameterValues(parameterName)返回的String[]將轉換成目標組件類型的數組。由struts框架內部實現該方法。ActionForm子類應該定義下面的方法聲明。
          public void set([] value)
          public [] get();
              2.當bean的屬性是數組,且請求參數名使用索引符號parameterName[n],由request.getParameterValues(parameterName)返回的String[]將被認為僅容納一個簡單的值;僅String[0]被轉換成數組的組件類型。由struts框架內部實現該方法。ActionForm子類應該定義下面的方法聲明來接收索引參數。
          public void set(int index, value)
          public get(int index)
          上面的方法聲明遵循了javabeans規范中定義的索引屬性設計模式。當這些方法都沒有時,通過實現下面的方法也可以處理索引存取屬性。
          public [] get();
          在這個場景中,請求數組的讀寫是通過struts框架處理,首先獲得根本的數組對象然后處理給定序號的元素。這個模式也支持基于list的請求參數實現,使用parameterName[n]訪問。
               3.對于簡單的屬性類型,由request.getParameterValues(parameterName)返回的String[]將被認為僅容納一個簡單的值;僅String[0]被轉換成目標類型。由struts框架內部實現該方法。對于簡單的屬性,ActionForm子類應該定義下面的方法聲明。
          public void set( value)
          public get();
          struts綁定的標簽庫提供了處理簡單屬性和索引屬性的方式;org.apache.struts.taglib.nested包容納了這些標簽。struts中的完全的標簽列表請參考http://jakarta.apache.org/struts/userGuide/index.html; 更多的資源請參考http://jakarta.apache.org/struts/resources/index.html. struts將來的趨勢是采用JSTL和
          JSF上。

          posted on 2005-06-09 09:09 塞翁 閱讀(271) 評論(0)  編輯  收藏 所屬分類: Java翻譯
          主站蜘蛛池模板: 嘉祥县| 铜梁县| 郓城县| 怀仁县| 景宁| 烟台市| 都江堰市| 钟祥市| 马公市| 武川县| 原阳县| 双桥区| 蓬溪县| 政和县| 上犹县| 无为县| 阳信县| 和顺县| 霍林郭勒市| 瑞丽市| 丰顺县| 东丰县| 和硕县| 南澳县| 浮山县| 洞口县| 固阳县| 宁明县| 琼中| 资兴市| 青海省| 海安县| 大足县| 三原县| 敦化市| 来安县| 武平县| 宁乡县| 仁布县| 苗栗市| 晋中市|