北極心空
在我已往的Struts 1.x項目經驗中,有個問題不時的出現——在創建FormBean時,對于某個屬性到底應該用String還是其它類型?
開發Web應用程序與開發傳統桌面應用程序不同,Web應用程序實際上是分布個不同的主機(當然也可以同一個主機,不過比較少見)上的兩個進程之間互交。這種互交建立在HTTP之上,它們互相傳遞是都是字符串。換句話說, 服務器可以的接收到的來自用戶的數據只能是字符串或字符數組,而在服務器上的對象中,這些數據往往有多種不同的類型,如日期(Date),整數(int),浮點數(float)或自定義類型(UDT)等,如圖1所示。因此,我們需要服務器端將字符串轉換為適合的類型。
同樣的問題也發生在使用UI展示服務器數據的情況。HTML的Form控件不同于桌面應用程序可以表示對象,其值只能為字符串類型,所以我們需要通過某種方式將特定對象轉換成字符串。
要實現上述轉換,Struts 2.0中有位魔術師可以幫到你——Converter。有了它,你不用一遍又一遍的重復編寫諸如此類代碼:
Date birthday = DateFormat.getInstance(DateFormat.SHORT).parse(strDate);<input type="text" value="<%= DateFormat.getInstance(DateFormat.SHORT).format(birthday) %>" />
好了,現在讓我們來看一個例子。
在我的上一篇文章《在Struts 2.0中國際化(i18n)您的應用程序》的最后我舉了一個可以讓用戶方便地切換語言的例子,下面例子與其相似,但實現方法不同。
首先,如《在Struts 2.0中國際化(i18n)您的應用程序》的第一個例子一樣,創建和配置默認的資源文件;
接著,新建源代碼文件夾下的tutorial包創建HelloWorld.java文件,代碼如下:
然后,在源代碼文件夾下的struts.xml加入如下代碼新建Action:
再在Web文件夾下,新建 HelloWorld.jsp,代碼如下:
接下來,在源代碼文件夾的tutorial包中新建LocaleConverter.java文件,代碼如下:
再接下來,在源代碼文件夾下新建xwork-conversion.properties,并在其中添加如下代碼:
發布運行應用程序,在瀏覽器中鍵入http://localhost:8080/Struts2_Converter/HelloWorld.action,輸出頁面如圖2所示:圖2 HelloWorld英文輸出
在Locale輸入框中輸入“zh_CN”,按“Submit”提交,出現如圖3所示頁面:圖3 HelloWorld中文輸出
上述例子中,Locale文本輸入框對應是Action中的類型為java.util.Locale的屬性loc,所以需要創建一個自定義轉變器實現兩者間的轉換。所有的Struts 2.0中的轉換器都必須實現ognl.TypeConverter接口。 為了簡單起見,OGNL包也為你提供了ognl.DefaultTypeConverter類去幫助您實現轉換器。在例子中,LocaleConverter繼承了ognl.DefaultTypeConverter,重載了其方法原型為“public Object convertValue(Map context, Object value, Class toType)”的方法。下面簡單地介紹一下函數的參數:
對于一此經常用到的轉換器,如日期、整數或浮點數等類型,Struts 2.0已經為您實現了。下面列出已經實現的轉換器。
不知道大家是否遇過這種情況,在一個頁面里同時提交幾個對象。例如,在發布產品的頁面,同時發布幾個產品。我在之前一個項目就遇到過這種需求,當時用的是Struts 1.x。那是一個痛苦的經歷,我在Google搜了很久都沒有理想的結果。幸運的是,在Struts 2.0中這種痛苦將一去不復返。下面我就演示一下如何實現這個需求。
首先,在源代碼文件夾下的tutorial包中新建Product.java文件,內容如下:
然后,在同上的包下添加ProductConfirm.java類,代碼如下:
接看,在同上的包中加入ProductConfirm-conversion.properties,代碼如下:
再在struts.xml文件中配置ProductConfirm Action,代碼片段如下:
在WEB文件夾下新建AddProducts.jsp,內容如下:
在同樣的文件夾下創建ShowProducts.jsp,內容如下:
發布運行應用程序,在瀏覽器中鍵入http://localhost:8080/Struts2_Converter/AddProducts.jsp,出現如圖4所示頁面:圖4 添加產品頁面
按圖4所示,填寫表單,按“Submit”提交,出現圖5所示頁面:圖5 查看產品頁面
查看服務器的控制臺,有如下輸出:
上面的代碼并不復雜,但有幾點需要說明:
不知道大家在運行上面的例子時,有沒有填錯日期或數字情況,又或者您有沒有思考過這種情況?如果還沒有嘗試的朋友可以試一下,在第一行的Price和Date of production中輸入英文字母,然后按“Submit”提交。你會看到頁面為空白,再看一下服務器的控制臺輸出,有如下語句: 警告: No result defined for action tutorial.ProductConfirm and result input,它提示我們沒有為Action定義輸入結果,所以,我們應該在源代碼文件夾下的struts.xml中的ProductConfirm Action中加入以下代碼:
重新加載應用程序,刷新瀏覽器重新提交請求,這時頁面返回AddProducts.jsp,格式錯誤的輸入框的值被保留,如下圖6所示:圖6 沒有提示的錯返回頁面
當然,我們還可以在頁面上加上錯誤提示信息,通過在AddProducts.jsp的“<body>”后,加入下面代碼可以實現:
刷新瀏覽器,重新提交請求,出現如圖7所示頁面:圖7 帶提示的錯返回頁面
以上的功能的都是通過Struts 2.0里的一個名為conversionError的攔截器(interceptor)工作,它被注冊到默認攔截器棧(default interceptor stack)中。Struts 2.0在轉換出錯后,會將錯誤放到ActionContext中,在conversionError的作用是將這些錯誤封裝為對應的項錯誤(field error),因此我們可以通過<s:fielderror />來將其在頁面上顯示出來。另外,大家看第二和第三行的Price都被賦為0.0的值,而第一行則保留其錯誤值。這同樣是conversionError的功勞——沒有出錯的行調用的products[index].price(默認值為0.0),而出錯的行則會被賦為頁面所提交的錯誤值,這樣可以提供更好的用戶體驗。
Struts 2.0的轉換器簡化的WEB應用程序的模型,為我們的編程帶來極大的方便。
Copyright @ 蘆葦 Powered by: .Text and ASP.NET Theme by: .NET Monster