Struts 2.0——Converter轉換器——批量封裝對象(Bean)
Posted on 2012-02-20 21:47 LaozhonG 閱讀(522) 評論(1) 編輯 收藏 所屬分類: 技術不知道大家是否遇過這種情況,在一個頁面里同時提交幾個對象。例如,在發布產品的頁面,同時發布幾個產品。
首先,在源代碼文件夾下的tutorial包中新建Product.java文件,內容如下:
圖4 添加產品頁面
按圖4所示,填寫表單,按“Submit”提交,出現圖5所示頁面:
圖5 查看產品頁面
查看服務器的控制臺,有如下輸出:
轉換錯誤處理
重新加載應用程序,刷新瀏覽器重新提交請求,這時頁面返回AddProducts.jsp,格式錯誤的輸入框的值被保留,如下圖6所示:
圖6 沒有提示的錯返回頁面
當然,我們還可以在頁面上加上錯誤提示信息,通過在AddProducts.jsp的“<body>”后,加入下面代碼可以實現:
<div style="color:red">
<s:fielderror />
</div>
刷新瀏覽器,重新提交請求,出現如圖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),而出錯的行則會被賦為頁面所提交的錯誤值,這樣可以提供更好的用戶體驗。
上文中,還需要編寫一個轉換器,用于格式化日期輸入輸出!
本文轉自Max,更加詳細請看原文《轉換器(Converter)——Struts 2.0中的魔術師》
------------------------------------------------------
About Me's
------一個喜歡在一塊青石階上獨立行走的人
首先,在源代碼文件夾下的tutorial包中新建Product.java文件,內容如下:
1 package tutorial;
2
3 import java.util.Date;
4
5 publicclass Product {
6 private String name;
7 privatedouble price;
8 private Date dateOfProduction;
9
10 public Date getDateOfProduction() {
11 return dateOfProduction;
12 }
13
14 publicvoid setDateOfProduction(Date dateOfProduction) {
15 this.dateOfProduction = dateOfProduction;
16 }
17
18 public String getName() {
19 return name;
20 }
21
22 publicvoid setName(String name) {
23 this.name = name;
24 }
25
26 publicdouble getPrice() {
27 return price;
28 }
29
30 publicvoid setPrice(double price) {
31 this.price = price;
32 }
33 }
然后,在同上的包下添加ProductConfirm.java類,代碼如下: 2
3 import java.util.Date;
4
5 publicclass Product {
6 private String name;
7 privatedouble price;
8 private Date dateOfProduction;
9
10 public Date getDateOfProduction() {
11 return dateOfProduction;
12 }
13
14 publicvoid setDateOfProduction(Date dateOfProduction) {
15 this.dateOfProduction = dateOfProduction;
16 }
17
18 public String getName() {
19 return name;
20 }
21
22 publicvoid setName(String name) {
23 this.name = name;
24 }
25
26 publicdouble getPrice() {
27 return price;
28 }
29
30 publicvoid setPrice(double price) {
31 this.price = price;
32 }
33 }
1 package tutorial;
2
3 import java.util.List;
4
5 import com.opensymphony.xwork2.ActionSupport;
6
7 publicclass ProductConfirm extends ActionSupport {
8 public List<Product> products;
9
10 public List<Product> getProducts() {
11 return products;
12 }
13
14 publicvoid setProducts(List<Product> products) {
15 this.products = products;
16 }
17
18 @Override
19 public String execute() {
20 for(Product p : products) {
21 System.out.println(p.getName() + " | "+ p.getPrice() +" | " + p.getDateOfProduction());
22 }
23 return SUCCESS;
24 }
25 }
接看,在同上的包中加入ProductConfirm-conversion.properties,代碼如下:2
3 import java.util.List;
4
5 import com.opensymphony.xwork2.ActionSupport;
6
7 publicclass ProductConfirm extends ActionSupport {
8 public List<Product> products;
9
10 public List<Product> getProducts() {
11 return products;
12 }
13
14 publicvoid setProducts(List<Product> products) {
15 this.products = products;
16 }
17
18 @Override
19 public String execute() {
20 for(Product p : products) {
21 System.out.println(p.getName() + " | "+ p.getPrice() +" | " + p.getDateOfProduction());
22 }
23 return SUCCESS;
24 }
25 }
1 Element_products=tutorial.Product
再在struts.xml文件中配置ProductConfirm Action,代碼片段如下: 1 <action name="ProductConfirm" class="tutorial.ProductConfirm">
2 <result>/ShowProducts.jsp</result>
3 </action>
在WEB文件夾下新建AddProducts.jsp,內容如下:2 <result>/ShowProducts.jsp</result>
3 </action>
1 <%@ page contentType="text/html; charset=UTF-8"%>
2 <%@taglib prefix="s" uri="/struts-tags"%>
3 <html>
4 <head>
5 <title>Hello World</title>
6 </head>
7 <body>
8 <s:form action="ProductConfirm" theme="simple">
9 <table>
10 <tr style="background-color:powderblue; font-weight:bold;">
11 <td>Product Name</td>
12 <td>Price</td>
13 <td>Date of production</td>
14 </tr>
15 <s:iterator value="new int[3]" status="stat">
16 <tr>
17 <td><s:textfield name="%{'products['+#stat.index+'].name'}"/></td>
18 <td><s:textfield name="%{'products['+#stat.index+'].price'}"/></td>
19 <td><s:textfield name="%{'products['+#stat.index+'].dateOfProduction'}"/></td>
20 </tr>
21 </s:iterator>
22 <tr>
23 <td colspan="3"><s:submit /></td>
24 </tr>
25 </table>
26 </s:form>
27 </body>
28 </html>
在同樣的文件夾下創建ShowProducts.jsp,內容如下:2 <%@taglib prefix="s" uri="/struts-tags"%>
3 <html>
4 <head>
5 <title>Hello World</title>
6 </head>
7 <body>
8 <s:form action="ProductConfirm" theme="simple">
9 <table>
10 <tr style="background-color:powderblue; font-weight:bold;">
11 <td>Product Name</td>
12 <td>Price</td>
13 <td>Date of production</td>
14 </tr>
15 <s:iterator value="new int[3]" status="stat">
16 <tr>
17 <td><s:textfield name="%{'products['+#stat.index+'].name'}"/></td>
18 <td><s:textfield name="%{'products['+#stat.index+'].price'}"/></td>
19 <td><s:textfield name="%{'products['+#stat.index+'].dateOfProduction'}"/></td>
20 </tr>
21 </s:iterator>
22 <tr>
23 <td colspan="3"><s:submit /></td>
24 </tr>
25 </table>
26 </s:form>
27 </body>
28 </html>
1 <%@ page contentType="text/html; charset=UTF-8"%>
2 <%@taglib prefix="s" uri="/struts-tags"%>
3 <html>
4 <head>
5 <title>Hello World</title>
6 </head>
7 <body>
8 <table>
9 <tr style="background-color:powderblue; font-weight:bold;">
10 <td>Product Name</td>
11 <td>Price</td>
12 <td>Date of production</td>
13 </tr>
14 <s:iterator value="products" status="stat">
15 <tr>
16 <td><s:property value="name"/></td>
17 <td>$<s:property value="price"/></td>
18 <td><s:property value="dateOfProduction"/></td>
19 </tr>
20 </s:iterator>
21 </table>
22 </body>
23 </html>
發布運行應用程序,在瀏覽器中鍵入http://localhost:8080/Struts2_Converter/AddProducts.jsp,出現如圖4所示頁面: 2 <%@taglib prefix="s" uri="/struts-tags"%>
3 <html>
4 <head>
5 <title>Hello World</title>
6 </head>
7 <body>
8 <table>
9 <tr style="background-color:powderblue; font-weight:bold;">
10 <td>Product Name</td>
11 <td>Price</td>
12 <td>Date of production</td>
13 </tr>
14 <s:iterator value="products" status="stat">
15 <tr>
16 <td><s:property value="name"/></td>
17 <td>$<s:property value="price"/></td>
18 <td><s:property value="dateOfProduction"/></td>
19 </tr>
20 </s:iterator>
21 </table>
22 </body>
23 </html>

圖4 添加產品頁面
按圖4所示,填寫表單,按“Submit”提交,出現圖5所示頁面:

圖5 查看產品頁面
查看服務器的控制臺,有如下輸出:
Expert One-on-One J2EE Development without EJB | 39.99 | Mon Jun 2100:00:00 CST 2004
Pro Spring | 32.99 | Mon Jan 3100:00:00 CST 2005
Core J2EE Patterns: Best Practices and Design Strategies, Second Edition | 34.64 | Sat May 1000:00:00 CST 2003
Pro Spring | 32.99 | Mon Jan 3100:00:00 CST 2005
Core J2EE Patterns: Best Practices and Design Strategies, Second Edition | 34.64 | Sat May 1000:00:00 CST 2003
上面的代碼并不復雜,但有幾點需要說明:
- ProductConfirm文件中的for(Product p : productes)的寫法是J2SE 5.0中的新特性,作用遍歷products列表;
- List<Product>也是J2SE 5.0的才有的泛型(Generic);
- ProductConfirm-conversion.properties中“Element_products=tutorial.Product”是告訴Struts 2.0列表products的元素的類型為Product,而不是定義轉換器;
- 在AddProducts.jsp的<s:textfield>的name為“%{'products['+#stat.index+'].name'}”,%{exp}格式表示使用OGNL表達式,上述表達式的相當于<%= "products[" + stat.index + "].name" %>,至于<s:iterator>標志的用法可以參考原文主人博客的文章《常用的Struts 2.0的標志(Tag)介紹》。
轉換錯誤處理
不知道大家在運行上面的例子時,有沒有填錯日期或數字情況,又或者您有沒有思考過這種情況?如果還沒有嘗試的朋友可以試一下,在第一行的Price和Date of production中輸入英文字母,然后按“Submit”提交。你會看到頁面為空白,再看一下服務器的控制臺輸出,有如下語句: 警告: No result defined for action tutorial.ProductConfirm and result input,它提示我們沒有為Action定義輸入結果,所以,我們應該在源代碼文件夾下的struts.xml中的ProductConfirm Action中加入以下代碼:
1 <result name="input">/AddProducts.jsp</result>
重新加載應用程序,刷新瀏覽器重新提交請求,這時頁面返回AddProducts.jsp,格式錯誤的輸入框的值被保留,如下圖6所示: 
圖6 沒有提示的錯返回頁面
當然,我們還可以在頁面上加上錯誤提示信息,通過在AddProducts.jsp的“<body>”后,加入下面代碼可以實現:
<div style="color:red">
<s:fielderror />
</div>
刷新瀏覽器,重新提交請求,出現如圖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),而出錯的行則會被賦為頁面所提交的錯誤值,這樣可以提供更好的用戶體驗。
上文中,還需要編寫一個轉換器,用于格式化日期輸入輸出!
本文轉自Max,更加詳細請看原文《轉換器(Converter)——Struts 2.0中的魔術師》
------------------------------------------------------
About Me's
------一個喜歡在一塊青石階上獨立行走的人